class Base {
int m_var;
public:
Base(int var) : m_var(var) {} // 初始化列表:初始化而非賦值
};
執行順序:分配內存 → 初始化列表初始化成員 → 函數體執行。初始化列表相當於 int a = 10;,函數體賦值相當於 int a; a = 10;。
class Base {
int* p;
public:
Base(int v) : p(new int(v)) {}
Base(const Base& other) : p(new int(*other.p)) {} // 深拷貝
~Base() { delete p; }
};
觸發場景:用對象初始化對象、值傳遞參數、函數返回對象。參數必須是引用,否則無限遞歸。
class Derived : public Base {
int m_d;
public:
Derived(int b, int d) : Base(b), m_d(d) {} // 基類先構造,按繼承聲明順序
};
多繼承:按繼承聲明順序構造基類,初始化列表順序不影響實際順序。
class Base { public: Base(int b) : m_b(b) {} int m_b; };
class B1 : virtual public Base { public: B1(int b, int b1) : Base(b), m_b1(b1) {} int m_b1; };
class B2 : virtual public Base { public: B2(int b, int b2) : Base(b), m_b2(b2) {} int m_b2; };
class Derived : public B1, public B2 {
public:
Derived(int b, int b1, int b2, int d) : Base(b), B1(b,b1), B2(b,b2), m_d(d) {}
// 最遠派生類必須顯式調用虛基類構造函數,中間基類調用會被忽略
int m_d;
};
class Base {
public:
virtual ~Base() {} // 虛析構
};
class Derived : public Base {
char* str;
public:
Derived(const char* s) { str = new char[strlen(s)+1]; strcpy(str, s); }
~Derived() { delete[] str; }
};
int main() {
Base* p = new Derived("hello");
delete p; // 正確調用 Derived::~Derived() 再 Base::~Base()
}
多態刪除基類指針指向的派生類對象時,必須將基類析構函數聲明為 virtual,否則只調用基類析構導致派生類資源洩漏。