Inheriting constructors

2018-12-31 17:00发布

问题:

Why does this code:

class A
{
    public: 
        explicit A(int x) {}
};

class B: public A
{
};

int main(void)
{
    B *b = new B(5);
    delete b;
}

Result in these errors:

main.cpp: In function ‘int main()’:
main.cpp:13: error: no matching function for call to ‘B::B(int)’
main.cpp:8: note: candidates are: B::B()
main.cpp:8: note:                 B::B(const B&)

Shouldn\'t B inherit A\'s constructor?

(this is using gcc)

回答1:

In C++03 standard constructors cannot be inherited and you need to inherit them manually one by one by calling base implementation on your own.

If your compiler supports C++11 standard, there is a constructor inheritance. For more see Wikipedia C++11 article. With the new standard you write:

class A
{
    public: 
        explicit A(int x) {}
};

class B: public A
{
     using A::A;
};


回答2:

Constructors are not inherited. They are called implicitly or explicitly by the child constructor.

The compiler creates a default constructor (one with no arguments) and a default copy constructor (one with an argument which is a reference to the same type). But if you want a constructor that will accept an int, you have to define it explicitly.

class A
{
public: 
    explicit A(int x) {}
};

class B: public A
{
public:
    explicit B(int x) : A(x) { }
};

UPDATE: In C++11, constructors can be inherited. See Suma\'s answer for details.



回答3:

You have to explicitly define the constructor in B and explicitly call the constructor for the parent.

B(int x) : A(x) { }

or

B() : A(5) { }


回答4:

This is straight from Bjarne Stroustrup\'s page:

If you so choose, you can still shoot yourself in the foot by inheriting constructors in a derived class in which you define new member variables needing initialization:

struct B1 {
    B1(int) { }
};

struct D1 : B1 {
    using B1::B1; // implicitly declares D1(int)
    int x;
};

void test()
{
    D1 d(6);    // Oops: d.x is not initialized
    D1 e;       // error: D1 has no default constructor
}


回答5:

Correct Code is

class A
{
    public: 
      explicit A(int x) {}
};

class B: public A
{
      public:

     B(int a):A(a){
          }
};

main()
{
    B *b = new B(5);
     delete b;
}

Error is b/c Class B has not parameter constructor and second it should have base class initializer to call the constructor of Base Class parameter constructor



回答6:

How about using a template function to bind all constructors?

template <class... T> Derived(T... t) : Base(t...) {}