首页 > 代码库 > c++--类的构造函数与拷贝控制
c++--类的构造函数与拷贝控制
类(class)与结构体(struct)的位移区别在于:默认情况下,类的派生方式和访问权限是private的,struct的派生方式和访问权限是public的。
构造函数
构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。
特点1:不同于其他成员函数,构造函数不能被声明为const的(参见7.1.2,P231)。
当我们创建类的一个const对象时,直到构造函数完成初始化过程,对象才能真正取得其“常量属性”。因此,构造函数在const对象的构造过程中可以向其写值。
const Sales_data obj(); //const对象
const成员函数:
const的作用是修改隐式this指针的类型。默认情况下,this 的类型是指向类类型非常量版本的常量指针,如在Sales_data成员函数中,this 的类型是 Sales_data *const。这意味着,在默认情况下,不能把this绑定到一个常量对象上。所以,应该将那些“不会修改类对象”的成员函数定义为const 的。如string isbn();
1 string Sales_data::isbn() const //this 类型为 const Sales_data *const 2 {return this->isbn;}
合成默认构造函数
如果没有显式的定义构造函数,那么编译器会为我们隐式的定义一个合成的默认构造函数。
初始化规则:1,如果存在类内的初始值(有默认值),用他来初始化成员;2,否则,默认初始化该成员。
某些类(比如包含不能依赖默认初始化的类型成员时)不能依赖于合成的默认构造函数。一般要自定义默认构造函数。
默认构造函数(=default)
一般要为类定义一个默认构造函数(=default):
1 struct Sales_data 2 { 3 Sales_data()=default; //他的作用完全等同于合成默认构造函数 4 Sales_data(const string &s):bookNo(s){} 5 ... 6 }
有一种情况必须去掉“=defalut”的默认构造函数,就是:如果一个构造函数为所有的参数都提供了默认实参,则它就成了默认构造函数。
如果还有原来的“=default”版本,在“Sales_data A;”时,编译器不知道调用哪个版本的构造函数,将出现“二义性”。
构造函数初始值列表
如果成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些成员提供初始值。
//构造函数,版本1 Sales_data::Sales_data(const string &s,unsigned n,double p) { bookNo=s; units_sold=n; revenue=n*p; } //构造函数,版本2 Sales_data(const string &s,unsigned n,double p): bookNo(s),units_sold(n),revenue(p*n){}
版本2采用了初始值列表,两个版本效果相同。区别在于:版本2初始化了他的数据成员,二版本1对数据成员执行了赋值操作。
成员初始化的顺序:与它们在类定义中的出现顺序一致,第一个成员先被初始化,然后第2个,以此类推。构造函数初始值列表中初始值的前后位置不会影响实际的初始化顺序。
五种特殊的成员函数:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。
拷贝构造函数和移动狗制造函数定义了【当用同类型的另一个对象初始化本对象时做什么】。拷贝和移动赋值运算符定义了【将一个对象赋予同类型的另一个对象时做什么】。析构函数定义了【当此类型对象销毁时做什么】。
c++--类的构造函数与拷贝控制