简体   繁体   中英

Why are base Constructors inherited, How can i prevent it?

#include<iostream>
using namespace std;

int main(){
    class c1{
        public:
        c1(){
            cout<<"constructing c1";
        }

    };


    class c2:private c1{
        public:
        c2(){
            cout<<"constructing c2";
        }
    };
    c2 inst1;

}

q1. Even when the access is private, why is the base's c'tor called for derived object? ie why is c1() called even when class c1 is inherited as private?

q2. Here c1 is inherited, how can i prevent that from happening?

It's not inherited. c2 is-a c1 . There's a c1 sub-object that is part of the c2 object.

Any object needs to be constructed in order to be used, so the c2 constructor will call the c1 c'tor automatically (because it has no parameters, and can be used for default construction).

If you want further convincing that this happens, try adding a parameter to the c1 c'tor:

c1(int){
    cout<<"constructing c1";
}

Now it can't be used to default construct c1 . You'll get a nice error, which can be resolved by explicitly calling the base class c'tor in c2 with some integer value:

c2() : c1(0) {
    cout<<"constructing c2";
}

This has nothing to do with private or public inheritance. Constructor of derived class are called after constructor of base class is called, destructors are called in reversed order.

It's a fondamental key point of Object oriented programming

Here c1 in inherited, how can i prevent that from happening?

Short answer: You can't prevent it. Derived objects contain all parent objects as sub-objects, due to their inheritance. So in order to initialize the object as a whole, the compiler has no choice but calling each constructor for every subobject.

You can however influence the behaviour of the parent's constructor by calling it with certain arguments. Consider this:

class Base {
    Data _data;
protected:
    Base(bool load_from_cache) {
        if(load_from_cache) _data = read_cache();
        else _data = read_database();
    }
};

class Derived : public Base {
public:
    Derived() : Base{ true } { } // specify from where to read the data
};

There are many other possibilities for injecting a custom behaviour, like passing function objects, lambdas, CRTP, you say it.

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