• c++11 继承构造函数


    若基类拥有数量众多的不同版本的构造函数,而派生类中只有一些成员函数,则对于派生类而言,其构造函数就等同于构造基类。

    struct A {
     A(int i) {}
     A(double d, int i) {}
     A(float f, int i, const char* c) {}
     //...
    };
    
    struct B : public: A {
     B(int i): A(i) {}
     B(double d, int i): A(d, i) {}
     B(float f, int i, const char* c): A(f, i c) {}
     //...
     virtual void ExtraInterface() {}
    };

    如上,B继承于A,只添加了一个接口,但在构造B时想要拥有A这样的构造方法时,就必须一一透传各个接口。

    在C++中,如果派生类想要使用基类的成员函数,可以通过using声明来完成。如下:

    #include <iostream>
    using namespace std;
    
    struct Base {
     void f(double i) { cout << "Base: " << i << endl; }
    };
    
    struct Derived: Base {
    public:
    using Base::f; void f(int i) { cout << "Derived: " << i << endl;} }; int main() { Base b; b.f(4.5); // Base: 4.5 Derived d; d.f(4.5); // Base: 4.5 d.f(4); // Derived: 4
    return 0; }

    基类和派生类都声明了函数f,而使用过using声明后,派生类也可以使用基类版本的函数f,这样派生类中就有了两个f函数的版本。

    在c++11中,此方法扩展到构造函数上,子类可以通过using声明来声明继承基类的构造函数。在刚开始的代码可以改造成如下:

    struct A {
     A(int i) {}
     A(double d, int i) {}
     A(float f, int i, const char* c) {}
    };
    
    struct B : A {
     using A::A;
     virtual void ExtraInterface() {}
    };

    通过 using A::A的声明,将基类中的构造函数悉数集成到派生类B中。且标准继承构造函数和派生类的各种类默认函数(默认构造、析构、拷贝构造等)一样,是隐式声明的。意味着一个继承构造函数不被相关代码使用,则编译器不会为其产生真正的函数代码。

    若基类构造函数含有默认值,则对于继承构造函数来说,参数的默认值不会被继承,但会导致基类产生多个构造函数的版本,而这些函数版本都会被派生类继承。

    struct A {
     A(int a = 3, double b = 2.4);
    };
    
    struct B : A{
     using A::A;
    };

    A的构造函数可能有A(int = 3, double = 2.4); A(int = 3); A(const A &); A();则相应地,B中的构造函数也会有:

    B(int, double); B(int); B(const B &); B();

    若碰到继承构造函数冲突的问题,需要通过显示定义继承类的冲突的构造函数,阻止隐式生成相应的继承构造函数。如下:

    struct A { A(int) {} };
    struct B { B(int) {} };
    
    struct C: A, B {
     using A::A;
     using B::B; //会造成冲突
    };
    
    //使用显示定义来解决:
    struct C: A, B {
     using A::A;
     using B::B;
    
     C(int) {} //显示定义
    };

    注意的问题:

    如果基类的构造函数被声明为私有成员函数,或者派生类是从基类中虚继承的,那么就不能够在派生类中声明继承构造函数。且一旦使用继承构造函数,编译器就不会再为派生类生成默认构造函数。

    struct A { A(int) {}};
    
    struct B : A { using A::A; };
    
    B b; //B没有默认构造函数
  • 相关阅读:
    797. 所有可能的路径
    1286. 字母组合迭代器
    216. 组合总和 III
    77. 组合
    784. 字母大小写全排列
    90. 子集 II
    78. 子集
    47. 全排列 II
    46. 全排列
    40. 组合总和 II
  • 原文地址:https://www.cnblogs.com/sssblog/p/10202601.html
Copyright © 2020-2023  润新知