C++_用 using 语句继承基类的构造函数

1. 派生类没自己的构造函数,通过 using 关键字使用基类的构造函数

默认情况下,派生类会继承基类的所有成员,包括数据成员和函数成员,但不会继承基类的构造函数和析构函数,因为构造函数和析构函数的作用是创建和销毁对象,派生类通常需要有自己的构造和析构的逻辑。

但是,C++11 引入了using语句,使得派生类可以通过 using 关键字使用基类的构造函数,更方便地复用基类的构造逻辑。

#include <iostream>
#include <string>
using namespace std;
class Base
{
protected:
    int x;
public:
    // 基类的构造函数
    Base(int val=0 ) :x(val)
    {
        cout << "Base constructor, x: " << x << endl;
    }

    // 基类的析构函数
    ~Base()
    {
        cout << "Base destructor" << endl;
    }
};

class Derived : public Base
{
public:
    // 用 using 继承基类的构造函数
    using Base::Base;

    // 在派生类中增加其他成员函数
    void showX()
    {
        cout << "Derived showX(), x: " << x << endl;
    }
    // 派生类的析构函数
    ~Derived()
    {
        cout << "Derived destructor" << endl;
    }
};

int main()
{
    Derived d1(49);  // 有参,派生类没有自己的构造函数,直接调用基类的构造函数
    d1.showX();

    Derived d2;      // 无参,派生类没有自己的构造函数,直接调用基类的构造函数
    d2.showX();
    return 0;
}

运行结果显示
Base constructor, x: 49
Derived showX(), x: 49
Derived destructor
Base destructor

2. 派生类有自己的构造函数,派生类的构造函数优先被调用

例如,在派生类中, using Base::Base; 语句之后增加了如下代码,其余保持不变,
在这种情况下,由于派生类已经定义了所有的构造函数,using Base::Base;其实没有任何作用,可以去掉而不影响代码的行为。

    Derived()
    {
        cout << "Derived no params is called. x: " << x << endl;
    }

    Derived(int val):Base(val)
    {
        cout << "Derived is called. x: " << x << endl;
    }
int main()
{
    Derived d1(49);  
    d1.showX();

    Derived d2;     
    d2.showX();
    return 0;
}

运行结果显示如下:
Base constructor, x: 49
Derived is called. x: 49
Derived showX(), x: 49
Base constructor, x: 0
Derived no params is called. x: 0
Derived showX(), x: 0
Derived destructor
Base destructor
Derived destructor
Base destructor

当前代码的构造函数调用过程:
Derived d1(49);
调用的是派生类的有参构造函数Derived(int val) : Base(val)。在Base(val)的初始化列表中显式调用基类的构造函数Base(int),完成基类部分的初始化。

Derived d2;
在main中调用时,调用的是派生类的无参构造函数Derived()。在Derived()的构造函数体执行之前,自动调用基类的默认构造函数Base(int val=0)来初始化基类部分。

完整代码如下

#include <iostream>
#include <string>
using namespace std;
class Base
{
protected:
    int x;
public:
    // 基类的构造函数
    Base(int val=0 ) :x(val)
    {        cout << "Base constructor, x: " << x << endl;    }

    // 基类的析构函数
    ~Base()    {        cout << "Base destructor" << endl;    }
};

class Derived : public Base
{
public:
    // 用 using 继承基类的构造函数
    using Base::Base;               //  此时这句话已多余
    Derived()   {        cout << "Derived no params is called. x: " << x << endl;    }
    Derived(int val):Base(val)    {        cout << "Derived is called. x: " << x << endl;    }

    // 在派生类中增加其他成员函数
    void showX()    {        cout << "Derived showX(), x: " << x << endl;    }
    // 派生类的析构函数
    ~Derived()    {        cout << "Derived destructor" << endl;    }
};

int main(){
    Derived d1(49);  // 派生类构造函数
    d1.showX();

    Derived d2;      // 派生类构造函数
    d2.showX();
    return 0;
}

3. 小结

  • 当派生类定义了自己的构造函数(无参或有参)时,派生类的构造函数优先被调用。
  • 在派生类的构造过程中,无论是否存在 using Base::Base,在执行过程中,基类的构造函数总会优先于派生类的构造函数执行,以确保基类部分的正确初始化
  • 用 using Base::Base; 可以简化代码,当且仅当派生类没有定义自己的构造函数时,这一机制才生效
    -原因:using Base::Base;的主要目的是让派生类继承基类的构造函数。当派生类没有定义相应的构造函数(无参或有参)时,编译器会使用基类的对应构造函数进行对象的初始化。简化代码而已。但是,如果派生类已经定义了与基类构造函数参数相同的构造函数,那么派生类的构造函数会优先被调用,using Base::Base;不会再被使用。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dotdotyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值