0
#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? i.e why is c1() called even when class c1 is inherited as private?

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

rooni
  • 1,036
  • 3
  • 17
  • 33
  • Constructors is not inheriting. please read about constructors and inheritance. – Farhad Oct 26 '17 at 07:51
  • @StoryTeller I read about it. http://www.cplusplus.com/forum/general/17261/ thanks for your feedback. – Farhad Oct 26 '17 at 08:01
  • @rimiro: Your `c2` contains `c1` as a *base subobject*. That `c1` subobject has to be constructed somehow. That can only be done by a constructor of `c1` - no way around it. So no, you cannot prevent `c1`'s constructor from being invoked. – AnT stands with Russia Oct 26 '17 at 08:03
  • @rimiro - I'm not saying this to offend you, but your question history indicates you are learning C++ by trial and error. This is a self-destructive approach to learning C++. When you have the time, [take a look at the curated book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Get yourself a good introductory book and you'd see how much easier it becomes. – StoryTeller - Unslander Monica Oct 26 '17 at 08:05
  • @StoryTeller thankyou for your feedback but i am strictly following books and may because its my first time with oop i get confused quite often and ask on SO and i find you ansers quite helpful :) – rooni Oct 26 '17 at 08:34

3 Answers3

2

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";
}
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
0

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

sandwood
  • 2,038
  • 20
  • 38
  • What you write in the last sentence should be true, but some languages (e.g. Java) work differently. – lorro Oct 26 '17 at 09:07
  • I am not expert in Java. But as far as I understand for constructors sequence it works the same. There is no destructor due to garbage collector. Is this what you mean ? – sandwood Oct 26 '17 at 09:15
  • What I meant, in Java, parent ctor call in child class in an explicit call. OP seems to be confused due to lack of explicit ctor call (it's implicit as base has default ctor) and by not knowing where to put the call as a simple c1() won't work. My first comment might have been too brief on this and thus misleading. – lorro Oct 26 '17 at 09:21
0

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.

Jodocus
  • 7,493
  • 1
  • 29
  • 45