C++ 成员对象和封闭类
程序员文章站
2023-11-10 21:39:10
01 成员对象与封闭类 类里有其他对象则该对象叫 成员对象 ;有成员对象的类叫 封闭类 ; 上例中,如果 类不定义构造函数,则会使用默认的无参构造函数,那么下面的语句会编译出错: 因为编译器不明白 类中的 成员对象该如何初始化。 成员对象的初始化则没问题呢,因为用默认构造函数即可。 任何生成封闭类对 ......
01 成员对象与封闭类
类里有其他对象则该对象叫成员对象;有成员对象的类叫 封闭类;
class ctyre // 轮胎类 { public: // 有参数构造函数 // 初始化成员变量m_radius和m_width ctyre(int r, int w):m_radius(r),m_width(w) { } private: int m_radius; // 半径 int m_width; // 宽度 }; class cengine // 引擎类 { // 默认会有无参数构造函数 }; class ccar // 汽车类 -- 封闭类 { public: // 有参数构造函数 // 对成员变量m_price初始化,对成员对象tyre初始化 ccar(int p, int tr, int tw):m_price(p),tyre(tr,tw){} private: int m_price; // 价格 ctyre tyre; // 成员对象 cengine engine; // 成员对象 }; int main() { ccar car(10000,20,50); return 0; }
上例中,如果ccar
类不定义构造函数,则会使用默认的无参构造函数,那么下面的语句会编译出错:
ccar car;
因为编译器不明白ccar
类中的tyre
成员对象该如何初始化。engine
成员对象的初始化则没问题呢,因为用默认构造函数即可。
任何生成封闭类对象的语句,都要让编译器明白,对象中的成员对象,是如何初始化的。
具体的做法是:通过封闭类的构造函数的初始化列表。
02 封闭类构造函数和析构函数的执行顺序
- 封闭类对象生成时,先执行所有成员对象的构造函数,然后才执行封闭类的构造函数。
- 成员对象的构造函数执行顺序,与在封闭类定义成员对象的顺序一致。
- 当封闭类的对象消忙时,只需要记住一句话:先构造的对象,后析构,由于封闭类是最后才被构造的,所以封闭类对象最先析构。
class ctyre // 轮胎类 { public: ctyre(){ std::cout << "ctyre 构造函数" << std::endl; } ~ctyre(){ std::cout << "ctyre 析构函数" << std::endl; } }; class cengine // 引擎类 { public: cengine(){ std::cout << "cengine 构造函数" << std::endl; } ~cengine(){ std::cout << "cengine 析构函数" << std::endl; } }; class ccar // 汽车类 -- 3. 最后构造封闭类对象 { public: ccar(){ std::cout << "ccar 构造函数" << std::endl; } ~ccar(){ std::cout << "ccar 析构函数" << std::endl; } private: ctyre tyre; // 1. 先构构造该成员对象 cengine engine; // 2. 接着构造该成员对象 }; int main() { ccar car; return 0; }
执行结果:
ctyre 构造函数 cengine 构造函数 ccar 构造函数 ccar 析构函数 cengine 析构函数 ctyre 析构函数
03 封闭类的复制构造函数
class a { public: // 无参数构造函数 a() { std::cout << "a 构造函数" << std::endl; } // 复制构造函数 a(a & a) { std::cout << "a 复制构造函数" << std::endl; } }; class b { // 若没有声明构造函数和复制构造函数,则编译器会默认生成构造函数和复制构造函数 a a; // 成员对象 }; int main() { b b1; // b1对象 和 成员对象a都会执行无参数的构造函数 b b2(b1); // b2对象 和 成员对象a都会执行复制构造函数 return 0; }
输出结果:
a 构造函数 a 复制构造函数