I get the error: No appropriate default constructor for B. However, I don't understand why the compiler wants to call a default constructor, when I give the arguments ii and DONT want to call the default.
#include <iostream>
using namespace std;
class A {
int i;
public:
A(int ii) { i = ii; cout << "Constructor for A\n"; }
~A() { cout << "Destructor for A\n"; }
void f() const{}
};
class B {
int i;
public:
B(int ii) { i = ii; cout << "Constructor for B\n"; }
~B() { cout << "Destructor for B\n"; }
void f() const{}
};
class C:public B {
A a;
public:
C() { cout << "Constructor for C\n"; }
~C() { cout << "Destructor for C\n"; }
void f() const {
a.f();
B::f();
}
};
class D:public B {
C c;
public:
D(int ii) { B(ii); cout << "Constructor for D\n"; }
~D() { cout << "Destructor for D\n"; }
};
int main() {
D d(47);
}
Your parent constructor should be called in the initializer list:
class D:public B {
C c;
public:
D(int ii) : B(ii)/* <- */ { cout << "Constructor for D\n"; }
~D() { cout << "Destructor for D\n"; }
};
Note the /* <- */ comment. That needs to be changed.
What you are doing right now is to create an instance of B() in you class D constructor, which is not being used:
D(int ii) { B(ii); /* <- useless*/ }
D(int ii) { B(ii); cout << "Constructor for D\n"; }
Calls the default constructor of B. The B(ii) creates an temporary object of B which gets destructed as soon as constructor of D returns, In short it does not call the constructor for Base class of object which is being constructed.
Solution:
To be able to call a particular constructor of your Base class you should use Member Initializer list.
D(int ii) : B(ii)
{
}
This code:
class C:public B
{
C() { cout << "Constructor for C\n"; }
};
attempts to call B's default constructor.
You might want:
class C:public B
{
C() : B(0) { cout << "Constructor for C\n"; }
};
but that depends on your logic.
The following is also wrong:
D(int ii) { B(ii); cout << "Constructor for D\n"; }
it should be
D(int ii) : B(ii) { cout << "Constructor for D\n"; }
Calling the base class constructor in the body of the child class constructor merely creates a temporary object which doesn't do anything. To get the behavior you expect, you must call the constructor in the initializer list.
You're creating a D, which is derived from B -- but D's ctor doesn't pass a parameter to B's constructor, which would require that B have a default ctor.
To fix this, you typically need to write D to provide a parameter to B's ctor:
class D : public B {
C C;
public:
D(int ii) : B(ii) { cout << "ctor for D\n"; }
};
You need to realize that base and member subobjects are constructed by the time you enter the body of your constructor! That is, if you have a base or a member which doesn't have a default you need to pass its argument in the member initializer list:
D(int ii): B(ii) { std::cout << "constructor for D\n"; }
The object you constructed in your body of the D constructor is just a temporary object which doesn't really serve any purpose in your case (temporary object may be useful in some cases, though).
Related
while I'm writing some code regarding base class/derived class type variables, I encountered this somewhat weird situation. It goes like this :
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "A Con" << endl; }
virtual ~A() { cout << "A Dec" << endl; }
};
class B : A {
public:
A a;
B(A _a) : a(_a) {
cout << "B Con" << endl;
}
virtual ~B() { cout << "B Dec" << endl; }
};
int main()
{
A a;
B b(a);
}
I declared base class(A) type member variable in derived class(B), and then above code gives me this result :
OK, so first constructor and last constructor would be for 'a' in main function.
But what about the others? why destructors are called 5 times while constructors are only called 3?
My Guess is :
A Con -> a in main()
A Con -> b in main() (base class constructor)
B Con -> b in main() (derived class constructor)
A Dec -> temporary value passed in B(A _a) : a(_a), copy constructor is called...
B Dec -> b in main() (derived class destructor)
A Dec -> member variable in B class (A a;)
A Dec -> b in main() (base class destuctor)
A Dec -> a in main()
Am I right or wrong?
This:
B(A _a) : a(_a) {
cout << "B Con" << endl;
}
calls A's copy constructor, which you have not defined and which does not print anything. Add this to A:
A(A const&) { cout << "A Con (Copy)" << endl; }
And while you're at it, you may want A(A&&), A& operator=(A const&) and A& operator=(A&&) as well.
Here is the Answer.
A()
B(int)
C(int)
~C()
~B()
~A()
But I don`t know why I get this output.
class A {
public:
A() { cout << "A()\n"; }
~A() { cout << "~A()\n"; }
};
class B : public A {
public:
B() { cout << "B()\n"; }
B(int i) { cout << "B(int)\n"; }
~B() { cout << "~B()\n"; }
};
class C : public B {
public:
C() { cout << "C()\n"; }
C(int i) : B(i) { cout << "C(int)\n"; }
~C() { cout << "~C()\n"; }
};
void main() {
C *b = new C(3);
delete b;
}
C(int) explicitly calls B(int) in its member initialization list before then logging itself in its body.
B(int) implicitly calls A() before then logging itself in its body.
Base classes are constructed before derived classes. This is why you see the constructors logged as A(), then B(int), then C(int).
~C() implicitly calls ~B() at the end after logging itself.
~B() implicitly calls ~A() at the end after logging itself.
Base classes are destructed after derived classes. This is why you see the destructors logged as ~C(), then ~B(), then ~A().
Any decent C++ book or tutorial should cover how constructors and destructors are called in relation to each other in a parent/child hierarchy.
Here is some basic C++ outline of code:
#include <cstdlib>
#include <iostream>
#include <thread>
using namespace std;
class M {
public:
M() = default;
~M() {
cout << "Called ~M" << endl;
}
};
class A {
public:
A(int z) : _z(z) {
cout << "Called A(int z)" << endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
A() {
cout << "Called A()" << endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
A(const A& a) {
cout << "Called A(const A& a)" << endl;
_z = a._z;
}
A(const A&& a) {
cout << "Called A(const A&& a)" << endl;
_z = a._z;
}
A& operator=(const A& a) {
cout << "Called A& operator=(const A& a)" << endl;
if (&a != this) {
cout << "Executed A& operator=(const A& a)" << endl;
}
}
virtual ~A() {
cout << "Called ~A" << endl;
}
int poll() const { return _z; }
private:
M _m;
int _z = 300;
};
class B : public A {
public:
// _a(10)
B() : _a(std::move(A(10))) {
cout << "Called B()" << endl;
}
virtual ~B() {
cout << "Called ~B" << endl;
}
private:
const A& _a;
};
int main(int argc, char** argv) {
B b;
A* aPtr = &b;
A& aRef = (*aPtr);
cout << aRef.poll() << endl;
return 0;
}
from the setup above I get the following output:
Called A()
Called A(int z)
Called ~A
Called ~M
Called B()
300
Called ~B
Called ~A
Called ~M
My issue is the first line of the output (all the others make sense given the first). I am initializing the member _a in B() : _a(std::move(A(10))), this is forced as _a is const reference member. And the CTOR with int argument gets called as well, however why is the default CTOR called on A? Why no move CTOR? Therefore the temporary object simply seems constructed and destroyed, no real move is happening (as can be seen from the 300 output later on).
Now this issue does not seem related to the move per se but to the behaviour around the const reference member. Because if I change the initialization list to: B(): _a(10) I get the same issue: somehow the default object is assigned to the const reference member and the arguments in the initialization list are ignored. So for B(): _a(10) I get:
Called A()
Called A(int z)
Called B()
300
Called ~B
Called ~A
Called ~M
Basically why is the first line a default constructor? And how do I alter the code so that the 10 from the initialization appears instead of the 300 from the default?
Each object of type B has actually two subobjects of type A. One is the base-class subobject, and the other is the _a member subobject. You call the constructor for the member, but the base-class subobject is default-initialized since you haven't explicitly called its constructor in your initialization list.
You could do it by, for example, the following:
B() : A(arguments) //<--initialize the base-class subobject
, _a(std::move(A(10))) {
cout << "Called B()" << endl;
}
Your B both contains an instance of A and derives from A (which is probably a mistake).
You're passing 10 when you construct a temporary A object, then moving that into the member _a. You're leaving the base class subobject to be default initialized.
To fix that, you need to include the base class in the member initializer list:
B() : A(1010), _a(std::move(A(10))) {
cout << "Called B()" << endl;
}
This initializes the base class subobject of B with 1010 (to distinguish it from the member object).
If I were going to do this, I'd also initialize _a directly, so the ctor would look something like:
B() : A(1010), _a(10) { // ...
I'm playing with construting/destructing object. Here is what I've tried http://coliru.stacked-crooked.com/a/ff17cc5649897430:
#include <iostream>
struct B{
B(){ std::cout << "B()" << std::endl; }
B(int){ std::cout << "B(int)" << std::endl; }
};
struct A : virtual B
{
int B;
A(int a) : B(a) { std::cout << "A(int)" << std::endl; }
} a(10);
int main()
{
}
The program output is
B()
A(int)
Why? I explicitly specify the constructor of the class B to be invoked in the ctor-initializer.
The B(a) is constructing the B member variable. Name your variables better and you'll see what you want to see.
I'm getting confused why p->a() is calling B::a()?. Is there a paragraph somewhere in the C++ documentation/standard that describes this behavior well?
#include <iostream>
using namespace std;
class A {
public:
A() { cout << "A ctor" << endl; a_instance = this; }
static A *get_instance() { return a_instance; }
static A *a_instance;
void virtual a() { cout << "From base class" << endl; }
};
class B : public A {
public:
B() { cout << "B ctor" << endl; b_instance = this; }
static B *get_instance() { return b_instance; }
static B *b_instance;
void virtual a() { cout << "From derived class" << endl; }
};
A *A::a_instance = 0;
B *B::b_instance = 0;
main()
{
cout << "Create A" << endl;
A ab;
cout << "Create B" << endl;
B abc;
B *ptr = B::get_instance();
A *p = A::get_instance();
cout << "Called from A object type" << endl;
if (p) {
p->a();
}
}
When you create the variable abc, A's constructor sets a_instance to that instance. Despite p being a pointer to an A, since the instance is pointing to a B, it's correctly calling B::a().
To fix this behaviour, you could use the following:
A* A::get_instance()
{
static A a;
return &a;
}
B* B::get_instance()
{
static B b;
return &b;
}
and remove all code that has to do with a_instance and b_instance.
The B constructor calls the A constructor first. That replaces the a_instance that you'd already created.
This chaining of constructors is well defined in the standard. The base is always called first, so that the derived constructor is guaranteed to be working on a valid base object.
What you are experiencing is caused by the design error, which is based on A's constructor initializing the static member using this. Body of this constructor is invoked not only when you are creating the instance of A but also when you are creating the instance of any of its derived classes:
A() { /* ... */ a_instance = this; }
So when you create an instance of type B, before the body of B's constructor is executed, the body of A's constructor is executed at first - this overwrites member a_instance with this within a context of instance of type B, i.e. it makes a_instance to point to this new instance of type B.
What you could do is to place a static variable inside of the getInstance method:
class A
{
public:
static A* getInstance() {
static A s; // <-- instantiated upon first call
return &s;
}
void virtual foo() { std::cout << "From base class" << std::endl; }
protected:
A() { } // <-- protected constructor
~A() { }
A(const A&); // <-- protected copy constructor
A& operator=(const A&); // <-- protected assignment operator
};
then B:
class B : public A
{
public:
static B* getInstance() {
static B s; // <-- instantiated upon first call
return &s;
}
void virtual foo() { std::cout << "From derived class" << std::endl; }
protected:
B() { } // <-- protected constructor
~B() { }
B(const B&); // <-- protected copy constructor
B& operator=(const B&); // <-- protected assignment operator
};
and possible usage:
int main() {
A::getInstance()->foo();
B::getInstance()->foo();
}
that outputs:
From base class
From derived class
B constructor invokes A constructor...