Reputation: 405
I am trying to do an assignment in my book but I do not understand the output. When the main code in the program is run the output is:
B::B(3)
B::B() //why is this outputted
B::B(-3)
D::D(3)
It gets this from calling B::B(int n) {}
first and then B::B() {}
followed by the the next two lines which I get. So the program called the first one since it is declared as the constructor the class A in the function and it has to assign values, what I dont get is output line 2, why is B::B() {}
even called? it gets called as a constructor but shouldnt just the constructor with parameters get called?
class B {
public:
B(); //why is this called?
B(int n);
};
// Definitions of B
B::B() {
cout << "B::B()\n";
}
B::B(int n) {
cout << "B::B(" << n << ")\n";
}
class D : public B {
public:
D();
D(int n);
private:
B b;
};
// Definitions of D
D::D() {
cout << "D::D()\n";
}
D::D(int n) : B(n) {
b = B(-n);
cout << "D::D("<< n <<")\n";
}
int main(int argc, const char * argv[]) {
// insert code here...
D d(3);
return 0;
}
Upvotes: 0
Views: 170
Reputation: 24966
Your class D
contains two objects of type B
.
B
from inheritanceB
member named b
You could rewrite the constructor
D::D(int n) : B(n)
{
b = B(-n);
cout << "D::D("<< n <<")\n";
}
like
D::D(int n) : B(n), b()
{
b = B(-n);
cout << "D::D("<< n <<")\n";
}
where it is apparent where the B::B()
comes from. Thus your output is easily explained:
B::B(3) // base constructor of `D`
B::B() // default construction of `b` member
B::B(-3) // explicit construction inside D::D(int)
D::D(3) // D::D(int)
If you write
D::D(int n) : B(n), b(-n)
{
cout << "D::D("<< n <<")\n";
}
instead, there is only
B::B(3)
B::B(-3)
D::D(3)
left.
Addressing the comment:
Imagine D
to look like:
class D : public B
{
public:
D(int);
};
with the constructor definition
D::D(int v) { std::cout << "foo with " << v; }
then, the code
D d(3);
prints
B::B()
foo with 3
and it is perfectly valid as long as B
is default constructible.
If B
would lack a default constructor you'd get a compiler error and you'd want to rewrite the definition of D
to
D::D(int v) : B(3) { std::cout << "foo with " << v; }
Every direct base class or member that is not part of the constructors initializer list is default constructed (in case of a class type) or left uninitialized in case of a fundamental type.
Upvotes: 0
Reputation: 58927
First the base class constructor is called: B::B(3)
.
Then the constructor for the b
field is called: B::B()
.
Then the derived constructor body is executed (after all fields are constructed).
D
's constructor first constructs another B
on the line b = B(-n);
(so B::B(-3)
is printed), then prints D::D(3)
.
Upvotes: 3