Calling other functions from a C++ constructor - c++

Is it safe to call non-virtual functions, including the assignment operator, from the body of a constructor after all member variables have been initialized?

Yes - you can call other non-virtual member functions freely. You can call virtual functions if the most derived base class provides an implementation you happen to want.
Indeed, before C++11 let one constructor call another, it wasn't uncommon for several constructors to call a support function to perform shared initialisation.
operator= can be called in these circumstances - the crucial thing is that any clean-up it might attempt before assigning new state will find sane values to operate on - for example, pointers set to nullptr so delete is safe.
Note that any exceptions from other functions you call that are allowed to cause the constructor to exit (i.e. not caught and suppressed) will prevent the object coming into existence - same as for exceptions thrown directly from the constructor function.

Yes, constructor can make call to non-virtual functions.
Make sure all members have been initialized properly before calling assignment operator otherwise object will be in an inconsistent state.
Use the "Virtual Constructor idiom" when you want to call virtual functions from constructor.

Related

C++ Calling final virtual function in constructor

It's true that calling virtual function in constructor and destructor is not a good practice, and should be avoided. It's because virtual functions are affected by subclasses, but in constructing or destructing phase subclasses are not yet constructed(in constructing) or already destructed(in destructing).
However what happens if a virtual final function is invoked in constructor or destructor? I assume that there should be no problem, since it's not logically wrong.
Calling virtual function in constructor and destructor is forbidden because accessing to subclass' variable, not initialized yet, can occur in overridden version of virtual function, which is declared in the subclass.
While virtual final function is not, it's final and there's no way to access to subclass' variables.
But this is my assumption, and there could be any more reasons that calling virtual function in constructor or destructor is not reasonable.
So, in conclusion,
Is calling virtual final function in constructing/destructing phase is allowed in C++ standard?
If so, is it widely implemented to most C++ compilers?
If it's not, is there any reason for that?
Is calling virtual final function in constructing/destructing phase is
allowed in C++ standard?
Calling a virtual function during construction/destruction is well defined and completely legal except in the case of pure virtual functions.
Calling virtual function in constructor and destructor is forbidden
I don't know (nor cares) who says it's "bad" or "forbidden" from a stylistic point of view, code maintenance point of view... The ability to maintain code depends first on knowing the relevant language and tools well; not knowing what virtual calls do during these phases (*) will lead to misunderstand on the part of the maintainers which is fixed by selecting more experienced maintainers and not dumbing down the programming style.
(*) which aren't technically part of the "lifetime" of the object, which isn't even a very useful concept as objects are usable and used in their constructor (before their lifetime has started) in any non trivial program (I think the standard should simply suppress this unneeded concept).
accessing to subclass' variable, not initialized yet, can occur in
overridden version of virtual function, which is declared in the
subclass.
It can't. During construction of a base class subobject B (say by constructor B::B()), the type of the object is being constructed is by definition B.
overridden version of virtual function, which is declared in the
subclass.
No, there is no existing subclass object at that point, so there is no overriding.
While virtual final function is not, it's final and there's no way to
access to subclass' variables.
It makes no difference.
The dynamic type of a polymorphic object is established by a constructor, after the constructors for base classes and before constructing members.
If so, is it widely implemented to most C++ compilers?
In practice all compilers implement setting the dynamic type of an object by changing the one or many vtable pointers to point to appropriate vtables for the type; that is done as part of construction.
It means that during construction, the vptr value changes as derived objects are constructed.
First, the rule is: "Do not directly or indirectly invoke a virtual function from a constructor or destructor that attempts to call into the object under construction or destruction." That's not opinion. That's the SEI CERT coding standard. Original document at:
https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-cpp-coding-standard-2016-v01.pdf
and a link to the relevant rule OOP50-CPP at:
https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP50-CPP.+Do+not+invoke+virtual+functions+from+constructors+or+destructors.
In answer to the original question, there are several exceptions to this rule. One of those, OOP50-CPP-EX2, is if the function or class is marked as final. Then it cannot be overridden by a derived class. You can also explicitly qualify the function call.
And yes, final is widely implemented.

Is the initialization of data members part of constructor?

As far as I know, this initialization will be complemented before the function body of the constructor.
If the initialization of data members is the part of constructor, then it should be inlined when the contructor is inlined, otherwise on the contrary.
By the way, how about the constructor list? And is the destroy of data member part of deconstructor?
The assumption is wrong. Compilers may partially inline functions. It's even easier to do so for constructors and destructors as you can't take their address anyway.
Still, that's something you won't notice at C++ level, only if you inspect the assembly.
You can consider the member initialization part of the constructor for functional effects and the member destruction part of the destructor. But what is inlined and what is invoked is not guaranteed. This part is depends totally on the compiler you are using.

member functions and the copy constructor

You have to explicitly list all of the members that you want copied in a copy constructor, this means that you could set up a copy constructor to copy cut down versions of your object.
but how does the member function copying work? are all member functions automatically included? Is this because an object is really just the members and the functions just declare how a class can be used? Does this mean you could in theory create cut down objects with a copy constructor and then, for example, call a getter to get a member that doesn't exist in your copy?
Member functions are not stored in class instances. They're just regular functions. A vtable pointer can be stored however. It is used for dynamic dispatch of virtual member functions.
Normal member function calls are determined at compile time.
(as a side-note, there are some languages that do store copies of methods per-instance, although C++ isn't one of them)
Functions don't have a separate instance for each instance; the characteristic of a (non-static) member function isn't that it will be instantiated for each instance, but that it must be called on an instance, and will implicitly receive a pointer to the instance. There's no copying of functions. (In fact, functions—member or otherwise—can't be copied.)
There is probably a misunderstanding about what classes/objects are in C++. In some languges (e.g. python), objects can change (new variables/functions); in C++, objects are static, as specified in the class, so there can not be shrinked down version of your object.
The default copy constructor already does a member to member copy. If this is not enough (shallow copy <-> deep copy), you have to provide your own version of the copy constructor in which you have to do all the copying. Failing to copy a member will leave the copied version with an undefined or default member. It is best to avoid having to make your own copy constructor by avoiding dynamic memory and the likes.

Virtual Constructor Idiom - Virtuous Or Complete Utter Fallacy

One of the golden rules in C++ is that the life-time of an instance begins when its constructor completes successfully and ends when its destructor begins.
From this rule we conclude that it is NOT a good idea to call virtual methods in a constructor as the possible derived instance is not valid which would lead to undefined behavior.
The Virtual Constructor Idiom as mentioned in C++ FAQ 20.8 seems to indicate the contrary.
My question is:
What is the exact definition in the standard for defining the life time of objects relative to calls from their constructors and destructors?
and furthermore is the So called "Virtual Constructor Idom" valid?
I think you're confusing two separate (if vaguely related) things.
It is well-known that one shouldn't call virtual functions from constructors (directly or indirectly), for reasons discussed here.
What the FAQ is talking about is calling a constructor from a virtual function. In some sense it is the opposite of #1. The idea is to choose the constructor (i.e. the class) based on the dynamic type of some existing object.
An object exists as the type of the class the constructor belongs to when the constructor starts, the object just may be in an inconsistent state (which is fine, as execution is currently inside one of the object's methods). That is, an object that is actually of type Derived that inherits from Base is treated as a Base in Base constructors; this in any Base::Base() is treated as a Base *, no matter the actual type of the object that this points to. Calling virtual methods is fine. In a constructor, the virtual methods for the constructor's class will be called, rather than for the actual type of the object.
Your first question is covered in "Base class on the initialisation list of a derived class' copy constructor". The short answer is it's covered by § 12.7 2-3 of C++03.
The virtual constructor idiom is completely valid.

Constructors cannot be virtual, why? Not a dupe [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why do we not have a virtual constructor?
I know this has been asked before but I didn't understand the complex technical words used in the other answers.
I read on a community the reason that constructors cannot be virtual is
The ‘virtual’ mechanism works on a logically complete (completely constructed) object. We know that we use constructors to logically initialize our objects. In other words, the object is not completely constructed until the constructor has finished executing. Thus, we can’t have virtual constructors.
There is a misconception that by then virtual table is incomplete so we can’t have virtual constructors. Just before the constructor starts executing the virtual table is properly constructed and the ‘this’ pointer passed to the constructors. Moreover, virtual table mechanism is implementation depended, and finds no place in the C++ standard. And hence, to argue over this issue using the virtual table concept is illogical.
Now, as the constructor finishes executing any other function can be virtual. Destructor is no exception to this rule as it is a function. Virtual destructors are required in case we use a base class pointer to refer to a derived class object, use it, and then delete it. If we have virtual destructor, using ‘delete’, a chain of destructors is called starting from the derived to the base. But, had there been no ‘virtual’ in destructor only the base class destructor is called (and not the derived). This (may) generate inconsistencies in the program.
Is the above reason correct? The answer doesn't talk about the static and dynamic types of objects.
Virtual constructors don't make sense and aren't necessary. The only time you call a constructor is when creating an object. You need to know the type of an object in order to create it, so the static and dynamic types are the same, and the correct constructor to call is the one for that type.
That's why they aren't necessary. Why they don't make sense, is that when creating an object, base class constructors are called as well as derived class constructors. If the base class constructor was overridden in the derived class, is that supposed to mean that the base class constructor isn't called after all?
Other languages have virtual constructors, perhaps because constructors in those languages are methods, and they only have virtual invocation for non-static methods. But those other languages (Java and Python spring to mind) have to introduce special rules that constructors must/should construct their base class explicitly as a call from the constructor. C++ just does it (perhaps in an initializer list, if the base class constructor requires parameters), using non-virtual constructors, and there is no option to enter the body of the constructor with uninitialized base class sub objects.
To quote from The C++ Programming Language:
To construct an object, a constructor
needs the exact type of the object it
is to create. Consequently, a
constructor cannot be virtual.
Furthermore, a constructor is not
quite an ordinary function. In
particular, it interacts with memory
management routines in ways ordinary
member functions don’t. Consequently,
you cannot have a pointer to a
constructor.
It must be interesting to note that C++ do have an idiom called virtual constructor. You can read more about that here.
Yes, the reason is you need to have a pointer/reference to a complete object already before you can call a virtual function. When the constructor is being invoked there's no complete object yet. Even more, when you do new SomeClass() you don't even have a pointer yet - the pointer is returned upon the new statement is completed successfully.
The virtual keyword cannot be applied to a constructor since a constructor turns raw bits into a living object, and until there is a living object against which to invoke a member function, the member function cannot possibly work correctly. Instead of thinking of constructors as normal member functions on the object, imagine that they are static member functions that create objects. - C++ FAQs