C++成员对象和封闭类
一個類的成員變量如果是另一個類的對象,就稱之為“成員對象”。包含成員對象的類叫封閉類(enclosed class)
成員對象的初始化
創建封閉類的對象時,它包含的成員對象也需要被創建,這就會引發成員對象構造函數的調用。如何讓編譯器知道,成員對象到底是用哪個構造函數初始化的呢?這就需要借助封閉類構造函數的初始化列表。
構造函數初始化列表的寫法如下:
類名::構造函數名(參數表): 成員變量1(參數表), 成員變量2(參數表), …
{
//TODO:
}
對于基本類型的成員變量,“參數表”中只有一個值,就是初始值,在調用構造函數時,會把這個初始值直接賦給成員變量。
但是對于成員對象,“參數表”中存放的是構造函數的參數,它可能是一個值,也可能是多個值,它指明了該成員對象如何被初
#include <iostream> using namespace std;//輪胎類 class Tyre{ public:Tyre(int radius, int width);void show() const; private:int m_radius; //半徑int m_width; //寬度 }; Tyre::Tyre(int radius, int width) : m_radius(radius), m_width(width){ } void Tyre::show() const {cout << "輪轂半徑:" << this->m_radius << "吋" << endl;cout << "輪胎寬度:" << this->m_width << "mm" << endl; }//引擎類 class Engine{ public:Engine(float displacement = 2.0);void show() const; private:float m_displacement; }; Engine::Engine(float displacement) : m_displacement(displacement) {} void Engine::show() const {cout << "排量:" << this->m_displacement << "L" << endl; }//汽車類 class Car{ public:Car(int price, int radius, int width);void show() const; private:int m_price; //價格Tyre m_tyre;Engine m_engine; }; Car::Car(int price, int radius, int width): m_price(price), m_tyre(radius, width)/*指明m_tyre對象的初始化方式*/{ }; void Car::show() const {cout << "價格:" << this->m_price << "¥" << endl;this->m_tyre.show();this->m_engine.show(); }int main() {Car car(200000, 19, 245);car.show();return 0; }Car 是一個封閉類,它有兩個成員對象:m_tyre 和 m_engine。在編譯第 51 行時,編譯器需要知道 car 對象中的 m_tyre 和 m_engine 成員對象該如何初始化。
編評器已經知道這里的 car 對象是用第 42 行的 Car(int price, int radius, int width) 構造函數初始化的,那么 m_tyre 和 m_engine 該如何初始化,就要看第 42 行后面的初始化列表了。該初始化列表表明:
m_tyre 應以 radius 和 width 作為參數調用 Tyre(int radius, int width) 構造函數初始化。
但是這里并沒有說明 m_engine 該如何處理。在這種情況下,編譯器就認為 m_engine 應該用 Engine 類的無參構造函數初始化。而 Engine 類確實有一個無參構造函數(因為設置了默認參數),因此,整個 car 對象的初始化問題就都解決了。
總之,生成封閉類對象的語句一定要讓編譯器能夠弄明白其成員對象是如何初始化的,否則就會編譯錯誤。
在上面的程序中,如果 Car 類的構造函數沒有初始化列表,那么第 51 行就會編譯出錯,因為編譯器不知道該如何初始化 car.m_tyre 對象,因為 Tyre 類沒有無參構造函數,而編譯器又找不到用來初始化 car.m_tyre 對象的參數。
成員對象的消亡
封閉類對象生成時,先執行所有成員對象的構造函數,然后才執行封閉類自己的構造函數。成員對象構造函數的執行次序和成員對象在類定義中的次序一致,與它們在構造函數初始化列表中出現的次序無關。
當封閉類對象消亡時,先執行封閉類的析構函數,然后再執行成員對象的析構函數,成員對象析構函數的執行次序和構造函數的執行次序相反,即先構造的后析構,這是 C++ 處理此類次序問題的一般規律。
請看下面的代碼:
#include<iostream> using namespace std; class Tyre { public:Tyre() { cout << "Tyre constructor" << endl; }~Tyre() { cout << "Tyre destructor" << endl; } }; class Engine { public:Engine() { cout << "Engine constructor" << endl; }~Engine() { cout << "Engine destructor" << endl; } }; class Car { private:Engine engine;Tyre tyre; public:Car() { cout << "Car constructor" << endl; }~Car() { cout << "Car destructor" << endl; } }; int main() {Car car;return 0; }總結
以上是生活随笔為你收集整理的C++成员对象和封闭类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++构造函数初始化列表
- 下一篇: C++ static静态成员变量详解