0

While running the code below, why is the constructor of the base class is derived first even if we first declare an object of derive class.

#include<iostream>

using namespace std;

class base {
  public:
    base()
    { cout<<"Constructing base \n"; }
    ~base()
    { cout<<"Destructing base \n"; }
};

class derived: public base {
  public:
    derived()
    { cout<<"Constructing derived \n"; }
    ~derived()
    { cout<<"Destructing derived \n"; }
};

int main(void)
{
  derived *d = new derived(); //d is defined ahead of the base class object
  base *b = d;
  delete b;

  return 0;
}
sam fisher
  • 183
  • 1
  • 10
  • What else would you expect and why exactly? – user0042 Jul 16 '17 at 13:04
  • 2
    Hint: There is a `base` **sub-object** inside `derived`. – StoryTeller - Unslander Monica Jul 16 '17 at 13:04
  • Question is not clear. Can you explain? – 9T9 Jul 16 '17 at 13:05
  • Note that your `delete` causes undefined behaviour due to lack of `virtual ~base()`. – HolyBlackCat Jul 16 '17 at 13:06
  • 1
    Objects are constructed bottom-up. `derived` has a base class of type `base`, so when you create an instance of `derived` you see a chain of constructors calls like: `base` -> `derived`. How would you put a roof on a house the walls of which are not in place yet? Bottom-up. That's all. – skypjack Jul 16 '17 at 13:07
  • i am asking why is it not printing the constructor of the derived class since we first created an object of derived class – sam fisher Jul 16 '17 at 13:07
  • 1
    Please check class data initialization rules [here](https://stackoverflow.com/questions/2669888/c-initialization-order-of-class-data-members). – Viktor Jul 16 '17 at 13:09
  • 1
    @samfisher It prints _constructing base_ and then _constructing derived_, for you **must** initialize a `base` object first of all if you want to create a `derived` one. The former is a sub-object of the latter. – skypjack Jul 16 '17 at 13:11

1 Answers1

4

Inheritance expresses an "is-a" relationship, so that all objects of class derived ARE objects of class base. derived objects have all of the data and methods that base objects do, plus the data and methods explicitly declared in the derived class declaration.

It's perfectly possible (and common) to write Derived classes that depend on the implementation of their Base classes. For example, suppose that we have

class Base {
public:
    Base() { n = 5; }
    int GetN() const { return n; }
private:
    int n;
};

class Derived : public Base {
public:
    Derived() { m = GetN() * 2; }
    int GetM() const { return m; }
private:
    int m;
};

Now we'd expect

Derived* d = new Derived();
std::cout << d->GetM() << std::endl;

to print 10, which is exactly what it should do (barring any mistakes on my part). This is a totally reasonable (if a little contrived) thing to do.

The only way the language can get code like this to work properly is to run the Base constructor before the Derived constructor when constructing an object of type Derived. This is because the Derived constructor depends on being able to call the GetN() method, which it inherits from Base, the proper functioning of which depends on the data member n having been properly initialised in the Base constructor.

To summarise, when constructing any Derived object, C++ must construct it as a Base object first because Derived is-a Base and will generally depend on it's implementation and data.

When you do

base* b = d;

in your code, you're declaring a variable b that is of type "pointer to a base object" and then initialising this variable with the same memory address held in d. The compiler doesn't mind you doing this because all derived objects ARE base objects, so it makes sense that you might want to treat d as a b. Nothing actually happens to the object here though, it's simply a declaration and instantiation of a pointer variable. The object pointed to by d already was a base object, since all derived objects are base objects.

Note that this explanation is intentionally a little fuzzy round the edges and is nowhere near a full explanation of the relationship between base and derived classes in C++. You'll want to go looking in other articles/books/the standard for that. I hope this is relatively easy to understand for beginners though.

JMAA
  • 1,730
  • 13
  • 24