control of base constructor in derived classes, potential double-initialization - c++

Regarding this question and the answer to it there does seem to be an exception, but it raised more questions for me than answering them. Consider this:
#include <iostream>
using namespace std;
struct base {
virtual void test() {cout << "base::test" << endl;}
base() {test();}
virtual ~base() {}
};
struct derived : base {
virtual void test() {cout << "derived::test" << endl;}
derived() : base() {}
~derived() {}
};
int main() {
derived d;
return 0;
}
I naively thought this would only print either of the two messages. It actually prints both - first the base version then derived. This behaves the same on -O0 and -O3 settings, so it's not an optimization or lack thereof as far as I can tell.
Am I to understand that calling base (or higher / earlier classes' constructors) within a derived constructor, will not prevent the default base constructor (or otherwise) from being called beforehand?
That is to say, the sequence in the above snippet when constructing a derived object is: base() then derived() and within that base() again?
I know it doesn't make sense to modify the vtable just for the purposes of calling base::base(), back to what it was before derived::derived() was called, just for the sake of calling a different constructor. I can only guess that vtable-related things are hard-coded into the constructor-chain and calling previous constructors is literally interpreted as a proper method call (up to the most-derived object having been constructed in the chain so far)?
These minor questions aside, it raises two important ones:
1. Is calling a base constructor within a derived constructor always going to incur calling the default base constructor prior to the derived constructor being called in the first place? Is this not inefficient?
2. Is there a use-case where the default base constructor, per #1, shouldn't be used in lieu of the base constructor explicitly called in a derived classes' constructor? How can this be achieved in C++?
I know #2 sounds silly, after all you'd have no guarantee the state of the base class part of a derived class was 'ready' / 'constructed' if you could defer calling the base constructor until an arbitrary function call in the derived constructor. So for instance this:
derived::derived() { base::base(); }
... I would expect to behave the same way and call the base constructor twice. However is there a reason that the compiler seems to treat it as the same case as this?
derived::derived() : base() { }
I'm not sure. But these seem to be equivalent statements as far as observed effects go. It runs counter to the idea I had in mind that the base constructor could be forwarded (in a sense at least) or perhaps a better choice of word would be selected within a derived class using :base() syntax. Indeed, that notation requires base classes to be put before members distinct to the derived class...
In other words this answer and it's example (forget for a moment its C#) would call the base constructor twice? Although I understand why it would be doing that, I don't understand why it doesn't behave more "intuitively" and select the base constructor (at least for simple cases) and call it only once.
Isn't that a risk of double-initializing the object? Or is that part-and-parcel of assuming the object is uninitialized when writing constructor code? worst case do I now have to assume that every class member could potentially be initialized twice and guard against that?
I'll end with a horrible example - but would this not leak memory? should it be expected to leak?
#include <iostream>
using namespace std;
struct base2 {
int * member;
base2() : member(new int) {}
base2(int*m) : member(m) {}
~base2() {if (member) delete member;}
};
struct derived2 : base2 {
derived2() : base2(new int) {
// is `member` leaking?
// should it be with this syntax?
}
};
int main() {
derived2 d;
return 0;
}

but would this not leak memory? should it be expected to leak?
no. The sequence of operations will be:
derived2::derived2()
auto p = new int
base2::base2(p)
base2::member = p
And for the destructor:
derived2::~derived2() (implied)
base2::~base2()
if (base2::member) { delete base2::member; }
One new, one delete. Perfect.
Don't forget to write correct assignment/copy constructors.

To construct derived class object compiler need to construct its base part. You can specify which base class constructor compiler should use by derived2() : base2(new int).
If you lack such specification, compiler will use base default constructor.
So, base constructor will be called only once, and long as your code did not cause memory leak there wouldn't be any one.

Related

Inheritance from std::enable_shared_from_this

I have next code:
class A
{
virtual ~A() = default;
virtual void foo1() = 0;
};
class B
{
virtual ~B() = default;
virtual void foo2() = 0;
};
class C: public A, public std::enable_shared_from_this<C>, public B
{
void foo1() override
{
}
void foo2() override
{
}
};
Is it correct that class std::enable_shared_from_this goes before class B? Does it matter where std::enable_shared_from_this is?
Does it matter where std::enable_shared_from_this is?
Technically it doesn't matter.
The order of derivation affects the order of constructor and destructor invocation.
From a construction perspective, enable_shared_from_this<T> constructor is a no-op; it simply adds a value-initialized, i.e. empty, weak_ptr-to-self to the class, and is detected by shared_ptr<T> constructor, which assigns itself to that member right after the object is fully constructed.
From a destruction perspective it also doesn't matter even if a destructor of another base before or after it throws. The destructor will still be invoked and the weak counter of the corresponding shared_ptr, if any, will be properly decremented, allowing it to be freed when the time comes (for the really curious, the exception cleanup rules can be found here).
It might matter from a code style perspective, however. For example, the following declaration is arguably more readable:
class C: public A, public B, public std::enable_shared_from_this<C>
. . .
It does not matter.
The order of base classes may affect:
Construction order (first base first, except for virtual inheritance)
Memory layout order (not deterministic, may not affect)
So, only construction order matters.
But you cannot use shared_from_this in a base class constructor/destructor anyway.
You cannot use it even in body of constructor or destructor of current class, as it will throw exception until it is placed inside shared_ptr<C>, or shared_ptr<D>, whatever. And you don't even have an easy way to attempt shared_from_this from base class, as you cannot call virtual functions from constructor of base class the way that the derived implementation is called.
So it does not matter at all.

Dynamic binding inside constructor for virtual Function in C++

As per the standard, we know that constructor always go for an early binding of a virtual function inside them because they don't have complete idea the derived class hierarchy downside.
In this case if early binding is used inside my base constructor, I have passed a derived object to a base class pointer which is completely acceptable (an upcasting is done here). If early binding is used the selection of the virtual function should be based on the type of the pointer (which is Base * here) but not the content of the pointer(the object pointed by the pointer because we don't know the exact object being pointed). In that case since the pointer type is Base * we should have invoked only Base class virtual function in both cases. Could some one please clarify this?
I think dynamic binding is used here rather than early binding. Please correct me if my understanding is wrong.
The first line of the output which invokes base is completely fine
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived : public Base
{
public:
void fun()
{
cout<<"In Derived"<<endl;
}
};
int main()
{
Derived d;
Base b(&d);
}
O/P :
In Base
In Derived
The rule for virtual calls within a constructor body applies to an object currently being constructed, because that object is not yet considered to be an object of any derived class. (And there's a similar rule for an object currently being destroyed.) It has little to do with "early binding" in the sense of using a compile-time type, such as the syntax ClassName::member_func() forces.
Your code has two different objects d and b, and the constructor of d has entirely finished by the time you get to the p->fun(); line.
In detail:
The program enters main.
The object d is created using the implicitly declared default constructor of Derived.
The first thing Derived::Derived() does is create the base class subobject, by calling the default constructor Base::Base().
The body of Base::Base() calls fun(). Since we have not yet entered the body of the Derived::Derived() constructor, this virtual lookup invokes Base::fun().
Base::Base() finishes.
The body of Derived::Derived(), which is empty, executes and finishes.
Back in main, the object b is created by passing a pointer to d to the constructor Base::Base(Base*).
The body of Base::Base(Base *p) calls p->fun(). Since p is a pointer to d, which is already a completely constructed object of type Derived, this virtual lookup invokes Derived::fun().
Contrast with this slightly different example, where we define a default constructor of Derived to pass this (implicitly converted to Base*) to the constructor for the Base subobject. (This is valid, though could be risky if the pointer were used in other ways, such as in an initializer for a base or member of Base.)
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public:
Base(){
fun();
}
Base(Base *p)
{
p->fun();
}
virtual void fun()
{
cout<<"In Base"<<endl;
}
};
class Derived
{
public:
Derived() : Base(this) {}
virtual void fun() override
{
cout << "In Derived" << endl;
}
};
int main()
{
Derived d;
}
This program will print just "In Base", since now in Base::Base(Base *p), p does point at the same object which is currently being constructed.
The reason is that C++ classes are constructed from Base classes to derived classes and virtual call table of the complete object is created when the object creation process is completed. Therefore, the base class function is called in the code excerpt above. Unless otherwise mandatory, you should never make virtual function calls in the constructor. Below is an excerpt from Bjarne Stroustrup's C++ Style and Technique FAQ:
In a constructor, the virtual call mechanism is disabled because
overriding from derived classes hasn’t yet happened. Objects are constructed from the base up, “base before derived”.
Destruction is done “derived class before base class”, so virtual
functions behave as in constructors: Only the local definitions are used –
and no calls are made to overriding functions to avoid touching the (now
destroyed) derived class part of the object.

Does C++ create default "Constructor/Destructor/Copy Constructor/Copy assignment operator" for pure virtual class?

Do C++ compilers generate the default functions like Constructor/Destructor/Copy-Constructor... for this "class"?
class IMyInterface
{
virtual void MyInterfaceFunction() = 0;
}
I mean it is not possible to instantiate this "class", so i think no default functions are generated.
Otherwise, people are saying you have to use a virtual destructor.
Which means if i dont define the destructor virtual it will be default created, not virtual.
Furthermore i wannt to know if it is reasonable to define a virtual destructor for a pure virtual Interface, like the one above? (So no pointers or data is used in here, so nothing has to be destructed)
Thanks.
Yes.
There is no wording that requires the class to be instantiable in order for these special member functions to be implicitly declared.
This makes sense — just because you cannot instantiate the Base, doesn't mean a Derived class doesn't want to use these functions.
struct Base
{
virtual void foo() = 0;
int x;
};
struct Derived : Base
{
Derived() {}; // needs access to Base's trivial implicit ctor
virtual void foo() {}
};
See:
§12.1/5 (ctor)
§12.8/9 (move)
§12.8/20 (copy)
Furthermore i wannt to know if it is reasonable to define a virtual destructor for a pure virtual Interface, like the one above? (So no pointers or data is used in here, so nothing has to be destructed)
It's not only reasonable, it's recommended. This is because in the case of virtual function hierarchies, (automatically) calling a destructor of a specialized class also calls all destructors of it's base classes. If they are not defined, you should get a linking error.
If you define at least one virtual function in your class you should also define a virtual destructor.
The destructor can be defined with =default though:
Here's a corrected (compilable) code example:
class ImyInterface
{
virtual void myInterfaceFunction() = 0;
virtual ~ImyInterface() = 0;
}
ImyInterface::~ImyInterface() = default;
Furthermore i wannt to know if it is reasonable to define a virtual destructor for a pure virtual Interface, like the one above? (So no pointers or data is used in here, so nothing has to be destructed)
Will the derived classes ever do anything in their destructors? Can you be certain they never will, even when somebody else takes over development?
The whole point of having a virtual destructor is not to make sure the base class is properly destructed, that will happen anyway. The point is that the derived class's destructor is called when you use a generic interface:
struct A {
virtual ~A() {}
virtual int f() = 0;
};
class B : public A {
std::ifstream fh;
public:
virtual ~B() {}
virtual int f() { return 42; }
};
std::shared_ptr<A> a = new B;
When a goes out of scope, why is the ifstream closed? Because the destructor deletes the object using the virtual destructor.
This addresses the second question about declaring a virtual destructor for an abstract base class (e.g. at least one member function is pure virtual). Here is a real world example of the LLVM clang++ compiler catching a potential problem. This occurred with the command line tools version supplied by Apple Developer for the Mac OS X Mavericks operating system.
Suppose you have a collection of derived classes that ultimately have the parent with the abstract base class to define the common interface. Then it is necessary to have a storage container like a vector that is intentionally declared to store a pointer to the abstract base class for each element. Later on, following good engineering practices, the container elements need to be "deleted" and the memory returned to the heap. The simplest way to do this is to traverse the vector element by element and invoke the delete operation on each one.
Well, if the abstract base class does not declare the destructor as virtual, the clang++ compiler gives a friendly warning about calling the non-virtual destructor on an abstract class. Keep in mind that in reality only the derived classes are allocated from the heap with operator new. The derived class pointer type from the inheritance relationship is indeed the abstract base class type (e.g. the is-a relationship).
If the abstract base class destructor is not virtual, then how will the correct derived class' destructor be invoked to release the memory? At best the compiler knows better (at least potentially does with C++11), and makes it happen. If the -Wall compiler option is enabled, then at least the compilation warning should appear. However, at worse, the derived class destructor is never reached and the memory is never returned to the heap. Hence there is now a memory leak that may be very challenging to track down and fix. All it will take is a single addition of "virtual" to the abstract base class destructor declaration.
Example code:
class abstractBase
{
public:
abstractBase() { };
~abstractBase() { };
virtual int foo() = 0;
};
class derived : abstractBase
{
public:
derived() { };
~derived() { };
int foo() override { return 42; }
};
//
// Later on, within a file like main.cpp . . .
// (header file includes are assumed to be satisfied)
//
vector<abstractBase*> v;
for (auto i = 0; i < 1000; i++)
{
v.push_back(new derived());
}
//
// do other stuff, logic, what not
//
//
// heap is running low, release memory from vector v above
//
for (auto i = v.begin(); i < v.end(); i++)
{
delete (*i); // problem is right here, how to find the derived class' destructor?
}
To resolve this potential memory leak, the abstract base class has to declare its destructor as virtual. Nothing else is required. The abstract base class now becomes:
class abstractBase
{
public:
abstractBase() { };
virtual ~abstractBase() { }; // insert virtual right here
virtual int foo() = 0;
}
Note that the abstract base class has currently empty constructor and destructor bodies. As Lightness answered above, the compiler creates a default constructor, destructor, and copy constructor for an abstract base class (if not defined by the engineer). It is highly recommended to review any of The C++ Programming Language editions by the C++ creator, Bjarne Stroustrup, for more details on abstract base classes.

C++ 11 Delegated Constructor Pure Virtual Method & Function Calls -- Dangers?

Not a Duplicate of Invoking virtual function and pure-virtual function from a constructor:
Former Question relates to C++ 03, not new Constructor Delegation behavior in C++ 11, and the question does not address the mitigation of undefined behavior by using delegation to ensure proper construction before pure virtual implementations are executed.
In C++ 11, what are the dangers of invoking Pure Virtual functions in a class' constructor, during construction, but after the class/object has been "fully constructed" via constructor delegation?
Apparently, somewhere in the C++ 11 spec such a constraint exists,
Member functions (including virtual member functions, 10.3) can be
called for an object under construction. Similarly, an object under
construction can be the operand of the typeid operator ..
- 12.6.2 #13 of the [C++ Working Draft] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf)
Can't find "Fair Use" version of Published Spec.
C++11 considers an object constructed once any constructor finishes
execution. Since multiple constructors will be allowed to execute,
this will mean that each delegate constructor will be executing on a
fully constructed object of its own type. Derived class constructors
will execute after all delegation in their base classes is complete.
- Wikipedia saying that this is a C++ 11 thing.
Actual C++ 11 Reference unknown.
Following Example Compiles AND RUNS in Nov CTP of Visual Studio 2012 C++ Compiler:
#include <string>
/**************************************/
class Base
{
public:
int sum;
virtual int Do() = 0;
void Initialize()
{
Do();
}
Base()
{
}
};
/**************************************/
// Optionally declare class as "final" to avoid
// issues with further sub-derivations.
class Derived final : public Base
{
public:
virtual int Do() override final
{
sum = 0 ? 1 : sum;
return sum / 2 ; // .5 if not already set.
}
Derived(const std::string & test)
: Derived() // Ensure "this" object is constructed.
{
Initialize(); // Call Pure Virtual Method.
}
Derived()
: Base()
{
// Effectively Instantiating the Base Class.
// Then Instantiating This.
// The the target constructor completes.
}
};
/********************************************************************/
int main(int args, char* argv[])
{
Derived d;
return 0;
}
With the updates, the example code looks okay to me, with the caveat that if you ever make a subclass of Derived, the subclass's override of Do() won't get called by Derived(const std::string &), rather Derived::Do() will still get called; which might not be what you wanted. In particular, when Initialize() is called from the Derived(const std::string &) constructor, the object is still "only" a Derived object and not a SubDerived object yet (because the SubDerived layer of construction-code hasn't started yet) and that is why Derived::Do() would be called and not SubDerived::Do().
Q: What if the subclass uses the same delegation pattern to ensure everything is instantiate in the same way?
A: That would mostly work, but only if it's okay for Derived::Do() to be called before SubDerived::Do() is called.
In particular, say you had class SubDerived that did the same things as Derived does above. Then when the calling code did this:
SubDerived foo("Hello");
the following sequence of calls would occur:
Base()
Derived()
Derived(const std::string &)
Base::Initialize()
Derived::Do()
SubDerived()
SubDerived(const std::string &)
Base::Initialize()
SubDerived::Do()
... so yes, SubDerived::Do() would eventually get called, but Derived::Do() would have been called also. Whether or not that will be a problem depends on what the various Do() methods actually do.
Some advice: Calling virtual methods from within a constructor is usually not the best way to go. You might want to consider simply requiring the calling code to call Do() manually on the object after the object is constructed. It's a bit more work for the calling code, but the advantage is that it you can avoid the not-very-obvious-or-convenient semantics that come into play when doing virtual method calls on partially-constructed objects.
In a typical single-constructor inheritance scenario, it is UB to call a pure virtual function in the base constructor:
[C++11: 10.4/6]: Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
struct Base
{
Base()
{
foo(); // UB
}
virtual void foo() = 0;
};
struct Derived : Base
{
virtual void foo() {}
};
There is no exemption here for such a call being made in a delegated constructor call, because at this point the more-derived part of the object still hasn't been constructed.
struct Base
{
Base()
{
foo(); // still UB
}
Base(int) : Base() {};
virtual void foo() = 0;
};
struct Derived : Base
{
virtual void foo() {}
};
Here's the Wikipedia passage that you cited:
C++11 considers an object constructed once any constructor finishes execution. Since multiple constructors will be allowed to execute, this will mean that each delegate constructor will be executing on a fully constructed object of its own type. Derived class constructors will execute after all delegation in their base classes is complete.
The key is the second bolded sentence, rather than the first, as one may misconstrue from a quick glance.
However, your posted code snippet is fine, and that's because the derived constructor body is undergoing execution, not the constructor for the abstract class, which has already been completely constructed. That said, the fact that you've had to ask for proof that it's safe should be some indication that this is not the most expressive or intuitive approach, and I would try to avoid it in your design.

How to call a derived class method from a base class method within the constructor of base

I am wondering if it is possible to call a derived class´ function from within a function called by the base constructor (shouldn´t it already be created when the code in the brackets are executed?)
#pragma once
class ClassA
{
public:
ClassA(void);
virtual ~ClassA(void);
void Init();
protected:
short m_a;
short m_b;
virtual void SetNumbers(short s);
};
include "ClassA.h"
#include <iostream>
ClassA::ClassA(void) : m_a(0), m_b(0)
{
Init();
}
ClassA::~ClassA(void)
{
}
void ClassA::SetNumbers(short s)
{
std::cout << "In ClassA::SetNumbers()\n";
m_a = s;
m_b = s;
}
void ClassA::Init()
{
this->SetNumbers(2);
}
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB(void);
virtual ~ClassB(void);
virtual void SetNumbers(short);
int x;
};
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(void)
{
}
ClassB::~ClassB(void)
{
}
void ClassB::SetNumbers(short s)
{
std::cout << "In ClassB::SetNumbers()\n";
m_a = ++s;
m_b = s;
ClassA::SetNumbers(s);
}
Any suggestions how to do it?...
Thank You in advance :)...
No. All parts of B (starting with A, as it's base) are constructed before B's constructor is called. So, by the time SetNumbers is called, no part of B (except for the A part) has been constructed --- and that may include the v-table, so there's no way to know where that call is going to go.
Of course, there is a simple solution to this: Call B::SetNumber() from within B's constructor (That is, after all, the purpose of B's constructor)
You can't do this for the simple logical reason that while the base class is being constructed, the derived class hasn't even begun to be constructed. You can't call a member function on an object that doesn't exist (yet).
In practice, even if you managed to call SetNumbers and assign to the member variables of the derived class before they were initialized they would surely be overwritten when they finally get initialized. I admit it's a bit pointless to reason about this as we would be well outside defined behaivour.
No, sorry. :( It might compile in one or two C++ compilers, but it's not recommended. From the C++ FAQ Lite section 10.7:
[10.7] Should you use the this pointer
in the constructor?
[...snip...]
Here is something that never works:
the {body} of a constructor (or a
function called from the constructor)
cannot get down to a derived class by
calling a virtual member function that
is overridden in the derived class. If
your goal was to get to the overridden
function in the derived class, you
won't get what you want. Note that you
won't get to the override in the
derived class independent of how you
call the virtual member function:
explicitly using the this pointer
(e.g., this->method()), implicitly
using the this pointer (e.g.,
method()), or even calling some other
function that calls the virtual member
function on your this object. The
bottom line is this: even if the
caller is constructing an object of a
derived class, during the constructor
of the base class, your object is not
yet of that derived class. You have
been warned.
NOTE: Emphasis mine.
More details at the link
The only time you can do this is when something is derived from a template that is parameterised by itself:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Note that doSomething is public and not virtual.
We can static_cast to derived, because it's known that derived is the derived type.
Deriving something from a base parameterised by itself is a strange thing to be doing at the best of times. It's said that when the ATL team in microsoft used it they asked the C++ compiler team if it was valid and nobody was sure, though it is valid because template construction depends on names as follows:
First the template is available, but not used in a class. Then, the name derived available. Then it instantiates the layout of base<derived> — this requires knowledge of the member variables and virtual functions, as long as none of that depends upon knowledge of derived’s layout (pointers and references are fine) this will all go okay. Then it will create the layout of derived, and finally it will create derived’s member functions, which may include creating member functions for base<derived>. So as long as base<derived> doesn’t contain a derived member variable (base classes can never contain a member variable of a type derived from themselves) or a virtual function that requires knowledge of derived’s layout we can indeed do the dicey-looking piece of inheritance above.
This includes being able to call non-virtual public members of derived from base during construction, because it's already part of base. There are strong limitations on this. In particular, if doSomething() depends on anything constructed in derived's constructor it won't work as derived hasn't been constructed yet.
Now, is this actually a good idea? No.
A simple design solution is to use aggregation instead of inheritance.