子类(派生类)调用父类(基类)构造函数

在 C++ 中,子类(派生类)调用父类(基类)构造函数需要通过 成员初始化列表(member initializer list) 实现。

一、基本规则

  1. 隐式调用如果基类有 默认构造函数(无参构造),且派生类构造函数未显式调用基类构造函数,编译器会自动调用基类的默认构造函数。
  2. 显式调用如果基类 没有默认构造函数,或需要调用基类的 带参构造函数,必须在派生类构造函数的初始化列表中显式指定。

二、代码示例

场景 1:基类有默认构造函数

class Base {
public:
    Base() {  // 基类默认构造函数
        cout << "Base默认构造" << endl;
    }
};

class Derived : public Base {
public:
    Derived() {  // 隐式调用 Base()
        cout << "Derived构造" << endl;
    }
};

int main() {
    Derived d;  // 输出顺序:Base默认构造 → Derived构造
    return 0;
}

场景 2:基类无默认构造函数(必须显式调用)

class Base {
public:
    Base(int x) {  // 基类带参构造(没有默认构造)
        cout << "Base带参构造: x=" << x << endl;
    }
};

class Derived : public Base {
public:
    Derived(int y) : Base(y * 2) {  // 显式调用 Base(int)
        cout << "Derived构造: y=" << y << endl;
    }
};

int main() {
    Derived d(5);  
    // 输出顺序:Base带参构造: x=10 → Derived构造: y=5
    return 0;
}

三、多继承与虚继承

多继承调用多个基类构造

class Base1 {
public:
    Base1(int a) { 
        cout << "Base1: a=" << a << endl; 
    }
};

class Base2 {
public:
    Base2(double b) { 
        cout << "Base2: b=" << b << endl; 
    }
};

class Derived : public Base1, public Base2 {
public:
    Derived(int x, double y) 
        : Base1(x), Base2(y) {  // 显式调用两个基类构造
        cout << "Derived构造" << endl;
    }
};

int main() {
    Derived d(10, 3.14);
    // 输出顺序:Base1: a=10 → Base2: b=3.14 → Derived构造
    return 0;
}

虚继承(Virtual Inheritance)

class Base {
public:
    Base(int x) { 
        cout << "Base构造: x=" << x << endl; 
    }
};

class Derived : virtual public Base {  // 虚继承
public:
    Derived(int a) : Base(a) { 
        cout << "Derived构造" << endl; 
    }
};

class FurtherDerived : public Derived {
public:
    FurtherDerived(int b) 
        : Base(b + 10),  // 虚基类构造必须由最底层派生类显式调用
          Derived(b) {
        cout << "FurtherDerived构造" << endl;
    }
};

int main() {
    FurtherDerived fd(5);
    // 输出顺序:Base构造: x=15 → Derived构造 → FurtherDerived构造
    return 0;
}

四、关键注意事项

  1. 初始化顺序基类构造函数总是先于派生类构造函数执行,且顺序由继承声明顺序决定(与初始化列表中的书写顺序无关)。
  2. 错误案例如果基类没有默认构造函数,且派生类未显式调用基类构造,将导致编译错误:
  3. C++11 继承构造函数使用 using Base::Base 直接继承基类构造函数:

通过合理使用初始化列表,可以精准控制基类构造函数的调用方式。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务