简体   繁体   中英

why constructors are called if they are not inherited?

the code is printing all the constructors. i read that constructors are not inherited when we derive a class from another class. then why creation of c is invoking constructors from b and a

class A
{
public:
  A()  { cout << "A's constructor called" << endl; }
};

class B
{
public:
  B()  { cout << "B's constructor called" << endl; }
};

class C: public B, public A  // Note the order
{
public:
  C()  { cout << "C's constructor called" << endl; }
};

int main()
{
    C c;
    return 0;
}

When the document you read said constructors are "not inherited", what it means is that if class A defines a constructor A::A(int x) , then a child class B will not automatically have a constructor that takes an int .

However, it's still necessary to initialize the values of the parent class; otherwise, the parent object might be in an invalid state. Constructors are used to initialize classes, so means one of the parent class' constructors must be called from the child constructor's initializer list . If the parent class has a default constructor, that one gets called by default. That's what you see in your example. If the parent doesn't provide a default constructor, you have to specify which one you want called:

class A
{
public:
  A(int x)  { cout << "A's constructor called" << endl; }
};

class C: public A
{
public:
  C()  
  : A(7)  /* compilation will fail without this line */
  { cout << "C's constructor called" << endl; }
};

i read that constructors are not inherited when we derive a class from another class

That is correct. However, you seem to have misunderstood the meaning of that.

Let's say you have:

struct A
{
   A(int) {}
};

struct B : A
{
   B() : A(0) {}
};

Given the above, you won't be able to use:

B b(10);

since A(int) is not inherited by B .

That's the crux of your misunderstanding.

then why creation of c is invoking constructors from b and a

However, when you construct a B , a constructor of B is called to initialize its members. A constructor of A must also be called so that the sub-object of B that corresponds to A can be initialized.

There are couple of ways to initialize the A -part of B .

  1. You can use a constructor of A explicitly in the member initialization list by using the syntax:

     B() : A(0) {} 
  2. Leave the member initialization empty, in which case the default constructor of A is called.

     B() {} 

    That is equivalent to:

     B() : A() {} 

    In the example I presented, that will result in a compiler error since the default constructor of A has been deleted by providing another constructor that is different than the default constructor.

Coming back to your implementation of the default constructor of C , you have:

C()  { cout << "C's constructor called" << endl; }

That is equivalent to

C() : B(), A() { cout << "C's constructor called" << endl; }

B::B() and A::A() are called when an instance of C is constructed.

Constructors are not inherited in the traditional sense.

Classes are what's inherited.

But in order to construct a class, its constructor needs to be called. That's its job. Hard rule, no exceptions.

When you inherit one class from a second class, constructing the first class requires the second class to be constructed too. Because the first class always contains the second class. Another hard rule, no exceptions. That's what "inheritance" means.

So, constructing the first class will invoke its constructor. Then, to construct the second class its constructor will also need to be called (actually the second class gets constructed first, then the first class's construction takes place).

And that's why both constructors will be used.

Constructors are called when classes are inherited. The inheritance basically gives the derived class instance anonymous member instances of the base classes, amongst other things. These instances need to be constructed so their constructors are called.

"Constructors are not inherited" means, that class C should and will have it's own constructors, despite fact that there were constructor of B, it will not be able to use constructor of B instead of constructor of C. And that's exactly what you get: you get constructors of all parent classes.

When you have hierarchy of classes, and construct object from one, there will be sequential construction of all his parents, starting from the base one.

And when you will destroy them, there will be sequential destruction of him and all his parents, starting from him.

By rule: first created -- last destructed.

By not inherited, C++11 standard means this

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

class B: public A
{
};

int main(void)
{
    B b(5);
    return 0;
}

This will fail to compile because A(int) is not inherited. You can define B to explicitly inherit A(int) by

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

In your case you are defining all default ctors, and which explicitly defined or not, still exist, and will be called as part of the object initialization due to your C c declaration.

C++ inheritance basically creates a class made of parts of its super-classes. For example:

class A {
    public:
        A() {
            std::cout << "Constructor A" << '\n';
        }
};

class B : public A {
    public:
        B() {
            std::cout << "Constructor B" << '\n';
        }
};

class C : public B {
    public:
        C() {
            std::cout << "Constructor C" << '\n';
        }
};

Class C is actually class C, with a class B part, and a class A part. So in order to construct class C, we need to construct each of its parts by calling the constructors for those parts. The order of these constructors is from the most-base class to the most-derived class (in this case A to C). Most-base being the class at the top of the inheritance tree, and most-derived being the class at the bottom.

This same rule applies to destructors as well. The only difference is that the destrutors are called from most-derived to most-base (C to A).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM