时间:2020年07月24日 | 作者 : aaronyang | 分类 : C++ | 浏览: 837次 | 评论 0 人
右键程序集-添加
AYUI www.ayjs.net AY 杨洋原创编写,请不要转载谢谢
多了一个.h文件,百度一下 .h和.cpp的区别,其他文章
.h文件是不对外隐藏的, .cpp文件在编译后对外隐藏---这是最本质的特点和区别
.h和.cpp文件本质上是没有什么区别的,.h文件实现的功能是声明本文件或.cpp文件中需要被别人使用或知道的变量、类型、函数及宏定义等。
.h文件就像是一个接口,具体的实现可以在.cpp中也可以在.h中。
.cpp中的函数或变量即便是全局的,在没有其他.cpp文件使用的情况下,也可以不写在.h中
首先,我们可以将所有东西都放在一个.cpp文件内.
然后编译器就将这个.cpp编译成.obj,obj是什么东西?
就是编译单元了.一个程序,可以由一个编译单元组成,
也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话,
就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上
就可以分别放在一个单元,也就是cpp里面)
那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序),
组成一个.exe,也就是程序了.
如果一个.cpp要用到另一个.cpp定义的函数怎么办? 只需在这个.cpp种写上他的函数声明
就可以了.其余工作由链接器帮你完成,你可以随便调用该函数.
链接器将所有的obj连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识别?
一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名.
但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个程序
公用的,还是只是在一个编译单元obj里面使用的.
这些关键字就是extern 和 static; extern是外部链接的意思,也就是除了这个单元,外部的单元
也是能够访问这个函数的.static 是内部链接,自属于自己单元.
说了这么久,还没有说.h的作用呢?
其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份
声明,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才
知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个
编译单元那里得到什么信息,知道你是如何定义这个函数的.
所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这样是不是很麻烦,
而且,如果要修改,就必须一个一个修改.这真让人受不了.
.h就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp,只需要
用#include包含进去便可.以后需要修改,也只是修改一份内容.
请注意不要滥用.h,.h里面不要写代码,.h不是.cpp的仓库,什么都塞到里面.
如果在里面写代码,当其他.cpp包含他的时候,就会出现重复定义的情况,
比如将函数func(){printf};放到头文件a.h,里面还有一些a.cpp需要的声明等;
然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来.
注意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝进来.
这时候实际上a.cpp和b.cpp都有一个func()函数的定义.
如果这个函数是内部链接static的话,还好,浪费了一倍空间;
如果是extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现
同名函数的要求,连接器会毫不留情给你一个连接错误!
不管咯,我们直接先在Box.h文件中定义个类,C++中类,分类定义和类实现两部分,C#直接在一个class里面。
这里只是类定义
#pragma once class Box { public: double length; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度 };
上方的#pragma once是vs2019新建时候,默认加上去的
#pragma once是一个比较常用的C/C++预处理指令,只要在头文件的最开始加入这条预处理指令,就能够保证头文件只被编译一次。
#ifndef,#define,#endif是C/C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式
方式一:
#ifndef _SOMEFILE_H_
#define _SOMEFILE_H_
.......... // 一些声明语句
#endif
方式二:
#pragma once
... ... // 一些声明语句
或者混用
#pragma once
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
除了public,还可以private 或 protected
发现了,访问修饰符只要写一遍,然后加个冒号,class类右花括号有个分号。
编写测试
int main() { Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box double volume = 0.0; // 用于存储体积 // box 1 详述 Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 详述 Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; // box 1 的体积 volume = Box1.height * Box1.length * Box1.breadth; cout << "Box1 的体积:" << volume << endl; // box 2 的体积 volume = Box2.height * Box2.length * Box2.breadth; cout << "Box2 的体积:" << volume << endl; system("pause"); return 0; }
发现代码不用new的,C#需要new
接下来,我们在Box.h中定义几个方法和构造函数,我们上面的例子只定义了3个属性
修改代码:
#pragma once #ifndef BOX_H #define BOX_H class Box { private: double factor; public: Box();//构造函数 Box(double factor);//带参数的构造函数 double PrintVolumn(); void PrintFactor(); double length; // 盒子的长度 double breadth; // 盒子的宽度 double height; // 盒子的高度 }; #endif
这里定义了3个public的方法,其中2个是构造函数,因为没返回值,名称也跟类名一样
这叫类定义,一般放到.h文件中
接着打开Box.cpp
定义这几个函数的实现,叫类实现
#include <iostream> #include "Box.h" using namespace std; Box::Box(void) { cout << "Box对象创建" << endl; } Box::Box(double factor) { this->factor = factor; cout << "Box对象创建,factor"<< this->factor << endl; } double Box::PrintVolumn() { return height * length * breadth; } void Box::PrintFactor() { cout << "PrintFactor,factor=" << this->factor << endl; }
注意实现的写法
返回类型 类名::函数(其他参数)
这样定义的,C#可以一步到位
无参构造函数的实现,括号需要加void,类定义不用,直接括号就行了。
接下来我们打开main方法的那个文件
我的是test2.cpp
顶部只需要引入
#include "Box.h"
h文件就行了,项目编译的时候,cpp和h文件会编译在一起,如果#include "Box.cpp"会报错的
demo1,调用默认参数
Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box double volume = 0.0; // 用于存储体积 // box 1 详述 Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 详述 Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; cout << "Box1 的体积:" << Box1.PrintVolumn() << endl; cout << "Box2 的体积:" << Box2.PrintVolumn() << endl;
Box Box1时候,调用了默认构造函数,输出Box对象创建,同理的Box2也是
创建Box对象时候,调用指定构造函数的写法
Box Box3(10); Box3.PrintFactor();
实例名,括号,传入参数值
感觉 类嵌套类,可以看这篇文章
如上代码可以简化写法
假如A类中引入了B类的东西,而B类的代码class B在 class A下面,就会报错,因为B还未知
在Class A中,可以写 B *b, 而不是B b,就行
比如下面代码就是报错的
#include using namespace std; class A { private: B b; public: void doSomething(); }; void A::doSomething() { b.doSomething(); } class B { public: void doSomething(); }; void B::doSomething() { cout<<"OK"<int main(int argc, char *argv[]) { A * a = new A; a->doSomething(); return 0; }
然后cpp文件
Box::~Box(void) { cout << "对象被删除了" << endl; }
运行后,我们按下回车,执行完整个程序,然后3个Box对象在释放内存之前,都执行了析构函数。
www.ayjs.net 六安杨洋(AY)
AYUI www.ayjs.net AY 杨洋原创编写,请不要转载谢谢
推荐您阅读更多有关于“C++,”的文章
抖音:wpfui 工作wpf,目前主maui
招聘合肥一枚WPF工程师,跟我一个开发组,10-15K,欢迎打扰
目前在合肥市企迈科技就职
AYUI8全源码 Github地址:前往获取
杨洋(AaronYang简称AY,安徽六安人)和AY交流
高中学历,2010年开始web开发,2015年1月17日开始学习WPF
声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费
不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo
查看捐赠AYUI7.X MVC教程 更新如下:
第一课 第二课 程序加密教程
额 本文暂时没人评论 来添加一个吧
发表评论