构造函数
在创建类的实例时。由编译器隐式的调用,在声明对象时不能显示的调用构造函数,即使是在创建之后也不能显式的调用
1 | clock c1.clock(1);//错 |
初始化数据成员的另一种方法
在构造函数的定义中函数体之前是初始化列表,他负责为创建的一个或几个数据成员指定初始值,效率更高,但是
1.构造函数的初始化顺序和定义顺序有关
2.只能初始化非静态数据成员
3.只能用于构造函数
4.适用于较为简单的情况,效率高
将默认构造函数和带形参的构造函数合并
1 | Clock(); |
合并
1 | Clock(int news=0);//直接赋初值 |
内联成员函数
为了提高运行时的效率,对于较简单的函数可以声明为内联形式
内联函数体中不要有复杂结构(如循环语句和switch语句)
在类中声明内联函数成员的方式:
隐式声明:将函数体放在类的声明中。
显式声明:使用inline关键字。
隐式内联
1 | class Point |
显示内联
1 | class Point |
复制构造函数
一种特殊的构造函数
形参为本类对象的(常/const)引用
使用一个已经存在的对象去初始化同类的一个新对象
用作为初始值的对象的每个数据成员的值去初始化将要建立的对象的对应数据成员
1 | class 类名 |
什么时候调用复制构造函数
1.当用类的一个对象去初始化该类的另一个对象时
2.当函数的形参为类的对象
3.从一个返回类型为非引用类型的函数返回一个对象时,编译器使用复制构造函数创建一个无名临时对象
析构函数
完成对象被删除前的一些清理工作
在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间
如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数
析构函数是构造函数的补操作,在类的实例停止存在时被自动调用
移动构造函数
复制构造函数通过复制的方式构造新的对象,但很多时候被复制的对象仅作复制之用后销毁,影响程序的性能
复制–>移动
左值(lvalue)和右值(rvalue)
在
1 | int i=a+b; |
中,i在表达式结束后依然会存在所以他是左值,而a+b在完成表达式后就会被销毁为右值
1 | int &p=i;//左值引用 |
左值无法接受右值和常量右值但是我们可以将左值引用改为常量左值引用这样他就能接受任何类型
常量左值引用:万能引用类型
可以接受:
左值、常量左值
右值、常量右值
非常量左值引用:只能接受左值
1 | A& a=fun(); //错误 |
类的组合
在类的组合中析构函数的调用顺序和构造函数完全相反
调用构造函数的的顺序
先调用内嵌对象的构造函数,内嵌对象的调用顺序与内嵌对象在构造函数的初始化列表中出现的顺序无关
再调用本类构造函数
注意事项1
如果调用组合类的默认构造函数时,则内嵌对象的初始化也将调用相应的默认构造函数
如果内嵌对象没有出现在构造函数的初始化列表中,那么调用内嵌对象的构造函数时该内嵌对象的默认构造函数将被执行。
注意事项2
必须在构造函数初始化列表中经行初始化
1.没有默认构造函数的内嵌对象
2.引用类型的数据成员
在这两种情况下编译器将不在为这个类提供默认构造函数,这时必须显式的编写构造函数。并且每个构造函数的初始化列表至少为这两类数据成员初始化。
前行引用声明注意事项
1.使用前向引用声明虽然可以解决一些问题,但是他并不是万能的
2.在提供一个完整的类声明之前不能声明该对象,不能在内联函数中使用该对象,使用前向引用声明时,只能使用被声明的符号,而不能涉及到具体细节
本文作者: jiangyuhao
本文链接: http://example.com/2022/03/21/%E7%B1%BB%E4%B8%8E%E5%AF%B9%E8%B1%A1/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!