316

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)

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
Sydius
  • 13,567
  • 17
  • 59
  • 76

8 Answers8

584

If your compiler supports C++11 standard, there is a constructor inheritance using using (pun intended). For more see Wikipedia C++11 article. You write:

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

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

This is all or nothing - you cannot inherit only some constructors, if you write this, you inherit all of them. To inherit only selected ones you need to write the individual constructors manually and call the base constructor as needed from them.

Historically constructors could not be inherited in the C++03 standard. You needed to inherit them manually one by one by calling base implementation on your own.


For templated base classes, refer to this example:

using std::vector;
    
template<class T>
class my_vector : public vector<T> {
    public:
    using vector<T>::vector; ///Takes all vector's constructors
    /* */
};
Antonio
  • 19,451
  • 13
  • 99
  • 197
Suma
  • 33,181
  • 16
  • 123
  • 191
  • 24
    This is quite evil because for over a year that has been no compiler that can actually build the above code :-) – Mikhail Jan 21 '13 at 04:51
  • 20
    @Mikhail: Both clang and g++ should now support inheriting constructors: http://clang.llvm.org/cxx_status.html http://gcc.gnu.org/projects/cxx0x.html Recommend upvoting this one as the correct answer. – Jan Korous May 05 '13 at 11:46
  • just asking, would an inherited constructor be able to access/initialize the base class's private members? Or would I have to specify them as protected? – markasoftware Jun 22 '14 at 05:13
  • 2
    @Markasoftware The code setting those members still belongs to the base class. The 'using' declaration just means that B gains a constructor which calls through to A's constructor. So your members can be private :) – entheh Oct 20 '14 at 21:18
  • 1
    MSVC++ still doesn't support inheriting constructors: https://msdn.microsoft.com/en-us/library/hh567368.aspx – Serge Rogatch Jul 06 '15 at 12:54
  • @SergeRogatch You are correct, but it seem to be coming eventually: http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx – Suma Jul 06 '15 at 13:02
  • 48
    I am a person from the future! MSVC 2015 claims support. – geometrian Jul 25 '15 at 04:34
  • 6
    Can you use this syntax to only inherit a specific constructor? – whoKnows Aug 05 '15 at 12:11
  • 3
    @whoKnows: No, this is all-or-nothing: http://en.cppreference.com/w/cpp/language/using_declaration – boycy Nov 07 '16 at 12:39
  • Thank you for a link. MUST KNOW!!! Just wanted to share my experiment: using Base::Base; statement should not necessarily reside in public section. It works everywhere, just like friend statement – Dmitry Babich Aug 19 '23 at 16:52
116

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.

nijoakim
  • 930
  • 10
  • 25
Avi
  • 19,934
  • 4
  • 57
  • 70
18

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
}

note that using another great C++11 feature (member initialization):

 int x = 77;

instead of

int x;

would solve the issue

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
nenchev
  • 1,998
  • 28
  • 16
  • In general, I wouldn't consider inheriting base class ctors as *shooting yourself in the foot*, but good practice - in those cases where this is possible. The cases where this is is possible are the ones where the subclass does not add members that require construction. However, if one modifies the subclass later and adds members that require initialization in the constructor, one has to change the constructor, too - and replace the inheritance by a custom constructor. If one forgets this when adding the subclass members, one shoots into the foot as if not updating a custom ctor. – HelpingHand Oct 04 '22 at 20:35
15

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) { }
Evan Teran
  • 87,561
  • 32
  • 179
  • 238
grepsedawk
  • 5,959
  • 5
  • 24
  • 22
8

How about using a template function to bind all constructors?

template <class... T> Derived(T... t) : Base(t...) {}
Pradu
  • 199
  • 1
  • 2
  • 8
    Probably you should do it with perfect forwarding: template < typename ... Args > B( Args && ... args ) : A( std::forward< Args >( args ) ... ) {} – Maxim Ky Jul 31 '15 at 10:58
  • 3
    And you just broke `Derived`'s copy constructor. – Barry Sep 14 '16 at 00:45
  • Would Base's constructor have to be templated too? When you call Base(t...), then Base would have to be templated for whatever t is? – Zebrafish Dec 26 '16 at 20:57
  • @Zebrafish: No, it doesn't. And even if it was, it wouldn't have to be templated in the same way. This is because when the Derived ctor is instantiated, it calls a Base ctor. This base ctor call is subject to the usual overload resolution given the (instantiated) arguments `t...`. That's why there is a warning about the copy ctor: this will blindly try to call `Base::Base(Derived const& src)`, which could very well slice the Base part of src. – MSalters Oct 11 '22 at 13:08
2

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

Iqbal Haider
  • 310
  • 1
  • 3
  • 9
2

Here is how I make the derived classes "inherit" all the parent's constructors. I find this is the most straightforward way, since it simply passes all the arguments to the constructor of the parent class.

class Derived : public Parent {
public:
  template <typename... Args>
  Derived(Args&&... args) : Parent(std::forward<Args>(args)...) 
  {

  }
};

Or if you would like to have a nice macro:

#define PARENT_CONSTRUCTOR(DERIVED, PARENT)                    \
template<typename... Args>                                     \
DERIVED(Args&&... args) : PARENT(std::forward<Args>(args)...)

class Derived : public Parent
{
public:
  PARENT_CONSTRUCTOR(Derived, Parent)
  {
  }
};
0

derived class inherits all the members(fields and methods) of the base class, but derived class cannot inherit the constructor of the base class because the constructors are not the members of the class. Instead of inheriting the constructors by the derived class, it only allowed to invoke the constructor of the base class

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

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

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