2

I wrote this small program to test my understanding. What I'm having trouble understanding is that constructors aren't inherited, but class B is able to call the constructor of class A!

#include <iostream>
using namespace std;

class A {
public:
    A(int x = 2) {          //Constructor A
        num = x;
    }
    int getNum() {
        return num;
    }

protected:
    int num;
};

class B: public A {         //Constructor B
public:
    B() {
        A(5);
    }
};

int main() {

    A a(3);                     //create obj a with num = 3
    B b;                        //create obj b
    cout << a.getNum() << endl;
    cout << b.getNum() << endl;
    return 0;
}

The output is:

3
2

What did the constructor A's call do exactly? It didn't use the passed argument to initialize object b's number!

Furthermore, if I remove the default value from class A's constructor, I get compilation error:

no matching function for call to 'A::A()'

So what's exactly happening here?

I know that the correct way is to do so:

class B: public A {         //Constructor B
public:
    B() : A(5) {
    }
};

Which gives the output:

3
5

But this is just for the purpose of understanding.

5
  • 2
    "I know that the correct way is to do so" So why not using the correct way? Commented Oct 27, 2017 at 4:36
  • B s constructor created a locally scoped object A by calling the A(int) constructor and then discarded the object. Commented Oct 27, 2017 at 4:38
  • 1
    @user0042, "But this is just for the purpose of understanding." Commented Oct 27, 2017 at 4:47
  • @MFisherKDX, and why does an A object changes the value of object B? Commented Oct 27, 2017 at 4:55
  • @LightXXV I posted an answer to try to clarify. Commented Oct 27, 2017 at 5:14

1 Answer 1

6

Lets take a look at the B constructor:

B() {
    A(5);
}

Here you actually "call" the A constructor twice. Once as part of the B construction (where the "default" A constructor is called), and once as you create a temporary object inside the B constructor body.

The sequence is as

  1. B constructor called
  2. A default constructor called as part of the initialization of the B object
  3. The body of the B constructor is entered
  4. A non-default constructor called (with argument 5) as part of creation of the temporary object
  5. The temporary object goes out of scope and is destructed
  6. The body of the B constructor exits
Sign up to request clarification or add additional context in comments.

4 Comments

I added this line inside A's constructor: cout << "A called" << endl; and got this output: A called A called A called 3 2.. the first 2 are for objects a and b, and the 3rd one is for the constructor you're claiming it's not getting called. Well, even if you're correct, then why it did affect object b's number? And why it didn't work the same way when I removed the default value (2) from the function definition?
@LightXXV I was in a little hurry before and got some things wrong. Updated answer.
I guess I will delete my answer since you updated yours.
Thank you.. now I get it. That means object b's number is set using the default constructor of parent class A with the default value, 2, since B() is a constructor with no arguments. And that's why it gave an error when I removed the default value as there's not a constructor A with no parameters to get called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.