一、成员对象和封闭类
(1)定义
一个类的成员变量如果是另一个类的对象,就称之为“成员对象”。
包含成员对象的类叫封闭类。
(2)封闭类构造函数的初始化列表
在构造函数中添加初始化列表的写法:
类名::构造函数名(参数表):成员变量1(参数表),成员变量2(参数表),···
{
···
}
“:”和“{”之间的部分就是初始化列表。初始化列表中的成员变量既可以是成员对象,也可以是基本类型的成员变量。
class CTyre //轮胎类 { private: int radius; //半径 int width; //宽度 public: CTyre(int r,int w):radius(r),width(w) { } }; class CEngine //引擎类 { }; class CCar { //汽车类 private: int price; //价格 CTyre tyre; CEngine engine; public: CCar(int p,int tr,int tw ); }; CCar::CCar(int p,int tr,int w):price(p),tyre(tr, w) { }; int main() { CCar car(20000,17,225); return 0; }
上例中,如果 CCar类不定义构造函数, 则下面的语句会编译出错:CCar car;
因为编译器不明白 car.tyre该如何初始化。CTyre类中的构造函数有参而默认构造函数无参。
car.engine 的初始化没问题,用默认构造函数即可。
任何生成封闭类对象的语句,都要让编译器明白,对象中的成员对象,是如何初始化的。具体的做法就是:通过封闭类的构造函数的初始化列表。成员对象初始化列表中的参数可以是任意复杂的表达式,可以包括函数,变量 ,只要表达式中的函数或变量有定义就行。
(3)封闭类构造函数和析构函数的执行顺序
封闭类对象生成时,先执行所有对象成员的构造函数,然后才执行封闭类的构造函数。
对象成员的构造函数调用次序和对象成员在类中的说明次序一致,与它们在成员初始化列表中出现的次序无关。
当封闭类的对象消亡时,先执行封闭类的析构函数,然后再执行成员对象的析构函数。次序和构造函数的调用次序相反。
class CTyre { public: CTyre() { cout << "CTyre contructor" << endl; } ~CTyre() { cout << "CTyre destructor" << endl; } }; class CEngine { public: CEngine() { cout << "CEngine contructor" << endl; } ~CEngine() { cout << "CEngine destructor" << endl; } }; class CCar { private: CEngine engine; CTyre tyre; public: CCar( ) { cout << “CCar contructor” << endl; } ~CCar() { cout << "CCar destructor" << endl; } }; int main(){ CCar car; return 0; }
输出结果:
CEngine contructor
CTyre contructor
CCar contructor
CCar destructor
CTyre destructor
CEngine destructor
(4)封闭类的复制构造函数
封闭类的对象,如果是用默认复制构造函数初始化的,那么它里面包含的成员对象,也会用复制构造函数初始化。
class A { public: A() { cout << "default" << endl; } A(A & a) { cout << "copy" << endl;} }; class B { A a; }; int main() { B b1,b2(b1); return 0; }
输出结果:
default copy
说明b2.a是用类A的复制构造函数初始化的。而且调用复制构造函数时的实参就是b1.a。
二、const成员和引用成员
类还可以有常量型成员变量和引用型成员变量。这两种类型的成员变量必须在构造函数的初始化列表中进行初始化。常量型成员变量的值一旦被初始化,就不能再改变。
#include<iostream> using namespace std; int f; class CDemo { private: const int num;//常量型成员变量 int& ref; //引用型成员变量 int value; public: CDemo(int n) :num(n), ref(f), value(4) { } }; int main() { cout << sizeof(CDemo) << endl; return 0; }
输出结果:
12