当前位置:   article > 正文

c++ 继承构造函数_c++ 继承 构造函数

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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

如上代码,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;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

这里没有在一个构造里初始化全部值只是举个例子,可以看到这里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;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

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

class TestB: public TestA{
public:
    // 继承构造函数
	using TestA::TestA; 
	// ....
    virtual void testb();
private:
    string b1{"b1"};
    int b2{0};
    ...
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/209111
推荐阅读
相关标签
  

闽ICP备14008679号