c++ 继承构造函数

c++ 继承构造函数

class TestA {
public:
    TestA(string i): a(i) {}
    ~TestA() {}
    string geta() {
        return a;
    }
    virtual string getb() = 0;
private:
    string a;
};

class TestB: public TestA{
public:
    TestB(string i):TestA(i),b(i) {}
    ~TestB() {}
    virtual string getb() override {
        return b;
    }
private:
    string b;
};

int main() {   
    string i("haha");
    TestA* testb = new TestB(i);

    cout << "A a:" << testb->geta() << endl;
    cout << "B b:" << testb->getb() << endl;
    return 0;
}

如上代码,TestB是TestA的派生类,TestB这里需要使用基类的构造函数来初始化基类的成员变量。相当于是构造函数的传递,所以在TestB中的构造函数里显示声明了TestA。
这样的话我们初始化TestB的成员变量时又同时初始化了TestA的成员变量。从这个意义上讲,这样的构造函数设计也是非常合理的。

但是,有的时候基类TestA可能有好多个构造函数。如果TestA有大量的构造函数,TestB只有一些成员函数,对于派生类而言,其构造等同于构造基类,这个时候我们就要写很多透传的构造函数。

比如:

class TestA {
public:
    TestA(string i): a1(i) {}
    TestA(int i) : a2(i) {}
    TestA(double i) : a3(i) {}
    ~TestA() {}
    string geta1() {
        return a1;
    }
    virtual string getb1() = 0;
private:
    string a1;
    int a2;
    double a3;
};

class TestB: public TestA{
public:
    TestB(string i):TestA(i),b1(i) {}
    TestB(int i) :TestA(i), b2(i) {}
    TestB(double i) :TestA(i), b3(i) {}
    ~TestB() {}
    virtual string getb1() override {
        return b1;
    }
    virtual void testb();
private:
    string b1;
    int b2;
    double b3;
};

这里没有在一个构造里初始化全部值只是举个例子,可以看到这里TestB继承TestA实际上只是添加了一个接口testb,如果在构造TestB的时候想要拥有TestA的所有构造方法的话,就必须一个个写,肯定不是很方便。

c++11里提供一个规则,派生类可以通过使用using声明来声明继承基类的构造函数。这样的话就可以如下代码来代替上面的代码:

class TestA {
public:
    TestA(string i): a1(i) {}
    TestA(int i) : a2(i) {}
    TestA(double i) : a3(i) {}
    ~TestA() {}
    string geta1() {
        return a1;
    }
    virtual string getb1() = 0;
private:
    string a1;
    int a2;
    double a3;
};

class TestB: public TestA{
public:
    // 继承构造函数
	using TestA::TestA; 
	// ....
    virtual void testb();
private:
    string b1;
    int b2;
    double b3;
};

这里通过using TestA::TestA的声明,把基类中的构造函数全部继承到派生类B中。
但是继承构造函数 只会初始化基类中的成员变量,对于派生类的成员变量,不会操作。
可以通过使用初始化表达式来解决这个问题,例如:

class TestB: public TestA{
public:
    // 继承构造函数
	using TestA::TestA; 
	// ....
    virtual void testb();
private:
    string b1{"b1"};
    int b2{0};
    ...
};

这里另外有一点需要注意的事,如果基类构造函数参数有默认值,默认值会导致基类产生多个构造函数的版本。这样都会被派生类继承。所以在使用有参数默认值的构造函数的基类,必须小心。

另外私有的构造函数,不会被继承构造。

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值