C++ 析構和構造

1. 析構爲構造的逆序,單繼承派生類只有一個基類或虛基類,根據四個優先級別確定構造順序;
  • 調用派生類虛基類的構造函數,無論列出總會被執行;
  • 調用派生類基類的構造函數,無論列出總會被執行;
  • 按照派生類實例數據成員聲明的順序,一次初始化實例數據成員或調用構造函數,對象無論是否列出總會被構造;
  • 最後執行派生類的構造函數;
2. 基類、對象成員不列出時自動調用無參構造函數;
3.以下情況派生類必須定義自己的構造函數:
  • 虛基類或基類只定義了帶參數的構造函數;-
  • 派生類自定義了引用或只讀成員(必須在冒號後列出以便初始化)而且不使用{}初始化全部都是公有成員的成員;
  • 派生類需要使用帶參數的構造函數。
#include <iostream>

using namespace std;
class A
{
    int a = 0;

public:
    A() : a(8) { cout << a; }//非const實例數據成員a,可在函數體內再次對a賦值
    A(int x) : a(x) { cout << "construct A "<<a; }
    ~A() { cout << "Destruct A" << a << endl; }
};
class B : A
{ //私有繼承,等價於class B: private A{
    int b, c;
    const int d;
    A x, y, z;

public:
    B(int v) : b(v), y(b + 2), x(b + 1), d(b), A(v)
    { //初始化與冒號後出現順序無關
    /*
       
        初始化 A(v) x y z 分別輸出 1 2 3 8
    */
        c = v;//b, c可再次賦值
        cout << b << c << d;
        cout << "C" << endl;
    }
    ~B() { cout << "Desturct B" << endl; }
};
int main()
{
    B z(1);
    return 0;
}
輸出結果
construct A 1
construct A 2
construct A 3
8
111C
Desturct B
Destruct A 8
Destruct A 3
Destruct A 2
Destruct A 1
注意:

  • 基類的靜態變量或全局變量
  • 派生類的靜態變量或全局變量
  • 基類的成員變量
  • 派生類的成員變量

  • 成員變量在使用初始化列表初始化時,與構造函數中初始化成員列表的順序無關,只與定義成員變量的順序有關。
  • 如果不使用初始化列表初始化,在構造函數內初始化時,此時與成員變量在構造函數中的位置有關。
  • 類中const成員常量必須在構造函數初始化列表中初始化。
  • 類中static成員變量,必須在類外初始化。

4. 關於引用變量

  • 若有址引用變量r引用的是一個對象v,則對象的
    構造和析構由對象v完成,而不應該由有址引用
    變量r完成;
  • 若被r有址引用的對象由自動調用構造函數的new
    生成,則r必須用能自動調用析構函數的delete &r
    析構並釋放對象內存,否則將產生內存泄漏;
  • 若被r指向的對象是用new生成的,則指針變量r必
    須用delete r析構並釋放對象內存,不能使用不調
    用析構函數的free®,否則將產生內存泄漏;

示例代碼
#include <iostream>

using namespace std;

class A
{
    int *s; //有私有實例數據成員,必須定義構造函數
public:
    A(int x)
    {
        s = new int[x];
    }
    ~A()
    {
        if (s)
        {
            delete s;
            s = 0; //相當於s=NULL
        }
    }
};
int main()
{
    A x(3),&r = x;//返回時自動析構x,r共享對象x不負責構造和析構
    A &p = *new A(5);//有值引用p被編譯成指針,p代表對象 A(5)
    A *q = new A(9);//分配一塊空間後,構造對象 即s分配一塊空間
    delete &p;// &p 表示取p 引用的對象的地址
    delete q;//釋放對象趙勇空間之前自動調用析構函數釋放 s
    return 0;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章