C++ Calling overwritten function in derived from base class - c++

I have 2 classes, A and B and I need an overwritten function in B to be called from A's constructor. Here is what I have already:
class A {
A(char* str) {
this->foo();
}
virtual void foo(){}
}
class B : public A {
B(char* str) : A(str) {}
void foo(){
//stuff here isn't being called
}
}
How would I get code to be called in B::foo() from A::A()?

I need an overwritten function in B to be called from A's constructor
This design is not possible in C++: the order of construction of a B object is that first the base A sub-object is constructed, then B is constructed on top of it.
The consequence is that, while in A constructor, you are still constructing an A object: any virtual function called at this point will be the one for A. Only when the A construction is finished and the B construction starts, will the virtual functions of B become effective.
For achieveing what you want, you have to use a two step pattern: 1) you construct the object, 2) you initialize it.

I think you are referring to Calling Virtuals During Initialization Idiom (aka Dynamic Binding During Initialization), so please have a look here, where everything is explained:
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Calling_Virtuals_During_Initialization
https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom
2nd site has very good explanation, but it's way longer than 1st.

In a constructor, the base class' function will get called, not the overridden version. The reason for this is that, using your example, B's initialization is not complete when A's constructor is called, and thus calling B's foo would be done with an incomplete B instance if this were otherwise allowed.

Related

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.

Explicit call to base copy constructor => RTTI info lost. Bug?

First of all:
I ask this question just out of curiosity, to understand what's really happening. I don't use in production code like this so I don't want to see answers suggesting another solution.
Having this code:
class Base{
public:
virtual void copy(){}
};
class Derived: public Base{
public:
void copy(){
Base a1;
this->Base::Base(a1);//explicit call to base copy constructor
}
};
I know that for some cases it is not good to call explicitly the copy constructor.(when classes have members allocated dynamically, because the reference to that memory area will be lost and it will not be freed anymore).
For the bellow example I don't see any direct problem for calling the base copy constructor. At the first sight I would think that the base sub-object must be reinitialized when copy() method is called.
int main(){
Base** _a = new Base*;
_a[0] = new Derived(10);
Derived* b = dynamic_cast<Derived*>(_a[0]);
assert(b);//<===true
_a[0]->copy();
//t is still available and can be accessed through b
std::cout<<b->t;//correct: 10
b = (Derived*)_a[0];
std::cout<<b->t;//correct: 10
b = dynamic_cast<Derived*>(_a[0]);
assert(b);//<===false
}
However the second assert fails. Can someone explain this behaviour? Why is this happening ? Is typeid lost when calling base copy constructor?
I compiled the code with Visual Studio 2012.
Constructor before class members initialization set the vptr pointer to the virtual function table of that class. Manually calling constructor of parent class you make derived class vptr point to vtable of the parent class.
Well, when you call Base::Base(const Base&), you are creating a new object of type Base in the memory allocated for your object of type Derived. After that, all virtual functions, for instance, will point to their Base:: implementations.
If you want to reinitialize your object, you must call the constructor of the derived type Derived::Derived(const Derived&), you can't just reinitialize part of it.
Aside:
You can make the reinitializetion correct by first destructing the object:
this->~Derived(); //cleanly destruct the object
this->Derived::Derived(...); //rebuilt the object in place

Inherited class data members

I am a bit confused, i was reading this C++ Constructor/Destructor inheritance, and so it says constructors and destructors are not inherited from the base class to the derived class but the constructors and destructors are called when i create a derived object. So is the constructors and destructors of the base class data members of the inherited classes?
Constructors and destructors are very special animals; in fact, the Standard identifies them as "Special Member Functions."
All the things that are weird and unique about constructors and destructors (for example, the fact that they don't have "names" and the fact that they aren't "inherited") is really quite irrelevant to almost all programming and programmers. Here is what you need to know:
Constructors and destructors are not member variables (obviously) -- they are (special) member functions.
When you derive from a base class, some constructor of the base class is going to be called. Which constructor depends on how you've written your code. If you don't explicitly specify which constructor to call, the default constructor will be called. This happens in your derived object's initialization list, even if you haven't written one.
You may specify another constructor through an initialization list, only:
class Bar : public Foo
{
public:
Bar()
:
Foo (1, 2, 3)
{
}
};
Here, Bar's initialization list specifies a constructor on Foo which takes 3 parameters convertible from integrals. One such constructor might be:
class Foo
{
public:
Foo (int a, long b, unsigned c)
:
mA (a),
mB (b),
mC (c)
{
}
private:
int mA;
long mB;
unsigned mC;
};
Back to the Bar example above. By the time the initialization list is done executing, and before the body of Bar's constructor starts, all of Bar's base classes and member variables have already been instantiated and initialized. This is why the only way to specify some constructor for Foo other than the default constructor is through an initialization list -- which, in turn, is why you must have an initialization list if the base class has no default constructor available.
Question: If constructors and destructors are not inherited, then why are they called when instantiating a derived type?
Answer: Because constructors are what initialize objects, and a derived type has an IS-A relationship with the base type.
Consider Foo and Bar above again. Bar derives from Foo, so in a sense Bar IS A Bar. It's more than just a Foo, it's got stuff that Foo doesn't have; but it has all the Foo-ness. Since a Bar object is in part a Foo, that Foo-ness has to be initialized. Since all initialization ob objects is done through a constructor, Foo's constructor must be called.
So, constructors and destructors aren't inherited in the sense of overloading -- but the constructors of the base class will be called. They have to be. Otherwise the Fooness of a Bar object could never come to be.
When you are deriving from a base class, something that you will often want to do is pass around a pointer to the base class. In fact, you may not need a pointer to the derived type at all in many cases. This is especially true when designing abstract interfaces.
There is a nasty problem that can come up when you do this and haven't taken all the needed preperations. Consider:
class Foo
{
public:
std::string mS;
};
class Bar : public Foo
{
public:
long mArray[0xFFFF]; // an array of 65K longs
};
int main()
{
Foo* thingy = new Bar; // Totally OK
// ... do stuff...
delete thingy; // WHOOPS! Memory leak!
}
Above in the delete call we're deleting through a base class pointer. The Foo destructor (which is implicit) is properly called, but the Bar destructor is not -- leaving that huge array of 65K longs leaked.
To fix this, we need to give Foo a virtual destructor:
class Foo
{
public:
std::string mS;
virtual ~Foo() {}
};
This doesn't do much, but it does one critical thing: it sets up polymorphism so that when we call the destructor (implicitly), the virtual override will get called.
This is a critical step when designing a class hierarchy. If you think there is any chance that people will pass around pointers to the base class, you should have a virtual destructor in the base class. In fact, I would suggest that in almost every case you should have a virtual destructor even if you don't think people will use it this way.
No. As you said, constructors and destructors are not inherited (by the way, the assignment operator isn't either). It would be logically flawed if they were inherited, right? Constructors (and destructors) are specific for that exact class; and since the derived class usually has something specific and new, the base constructor is not enough to initialize the inherited class objects.
So why is the base constructor called when creating an object of the child class?
Well, every derived object has a sub-object - which is the actual object of the parent class (I hope this sentence wasn't difficult to understand).
The compiler will:
1) locate the constructor of the derived class whose list of initializers best fits the arguments passed, but not execute it;
2) execute the constructor of the base class to create the sub-object;
3) execute the constructor of the derived class, to create the actual object.
I hope this is clear; you can find a much more detailed explanation in the answer above :)

Can we avoid the default constructor in this case?

Observation: The constructor of ClassMain needs to call Init before it can constructor a member variable a. Since the ClassA has no default constructor, the code doesn't compile.
ClassA
{
public:
// This class has no default constructor
ClassA(...){}
};
class ClassMain
{
public:
ClassMain(...) {
Init(...);
a = ClassA(...); // error: ClassA has no default constructor
// a has to been constructed after the Init is called!
}
ClassMain(...) {
Init(...);
call other functions
a = ClassA(...);
}
private:
// initialize environment
void Init(...) {}
private:
ClassA a;
};
Question> The simple solution is to provide a default constructor for ClassA. However, I would like to know whether there is a better solution to address the issue above?
The better solution is not to require an Init function at all. You're trying to reinvent constructors, and breaking their design in the process.
If Init does too much work for a constructor, then do it outside and pass the resulting resources into ClassMain as a constructor argument; notice how you're already doing all the work in the constructor's scope anyway, thereby not gaining anything appreciable over proper initialisation.
Of course, if you must perform a ton of work before initialising a, and you cannot pass in a ClassA& from the outside and initialise from that, then you're simply going to have to have a be an indirect member.
There is one nasty workaround you could use: have Init actually be a base constructor...
The obvious solution is to call Init() from the initializer list of an early member or a base class. Once this subobject is constructed its results can be passed to the constructors of other subobjects. For example, when defining stream classes I typically privately inherit from a virtual base containing the stream buffer:
struct somebuf_base {
somebuf sbuf;
// ...
};
class somestream
: private virtual somebuf_base
, public std::ostream
{
public:
somestream(someargs)
: somebuf_base(someargs)
, std::ostream(&this->sbuf) {
}
// ...
};
Since base classes are constructed in the order they appear but virtual bases before non-virtual bases, the base class containing the sbuf member is constructed first. Its constructor replaces your Init() function.
When using C++ as of the 2011 revision, you might also use forwarding constructors to share logic between multiple constructors.
It's easier to take a pointer to ClassA; So, you can instantiate it whenever you want.(after the init())
If you used a pointer, don't forget to implement the virtual destructor and release the allocated memory for the ClassA *a
If you absolutely must call some function at the start of your constructor, and can't put that setup into some base class or early-constructed member, you could use this ugly trick:
ClassMain::ClassMain(int main_param)
: a( (Init(init_arg), class_a_arg1), class_a_arg2 )
{
}
In this case: No, we cannot avoid that.
The reason is that when calling Init or any other member function you are guaranteed by the language that the object you are in exists. As a is a member of ClassMain it must be constructed before any function in ClassMain can be called.
The only chance that you have here is to refactor the code.

how functions of a not fully constructed objects are called?

creating an object using a constructor and along with that calling functions of object which is being constructed:
class A
{
public:
A()
{
this->show();
}
void show()
{
cout<<"show called!";
}
};
and now i m creating object in main() as below:
int main()
{
A a;
int xy;
cin>>xy;
return 0;
}
my doubt is that when i am creating an object using constructor then how i am able to call object function while object is not fully constructed?
virtual function calls:
class A
{
public:
A()
{
}
virtual void show()
{
cout<<"show called!";
}
};
class B:public A
{
public:
B()
{
A *a=this;
a->show();
}
void show()
{
cout<<"derived show";
}
};
int main()
{
A a;
B b;
int xy;
cin>>xy;
return 0;
}
working fine with output: derived show
It's fine to call virtual functions and non-static member functions:
See section 12.7 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf:
4 Member functions, including virtual functions (10.3), can be called
during construction or destruction (12.6.2).
However when using virtual functions in a constructor there are some restrictions. It's a bit of a mouthful:
When a virtual function is called directly or indirectly from a
constructor (including the mem-initializer or
brace-or-equal-initializer for a non-static data member) or from a
destructor, and the object to which the call applies is the object
under construction or destruction, the function called is the one
defined in the constructor or destructor’s own class or in one of its
bases, but not a function overriding it in a class derived from the
constructor or destructor’s class, or overriding it in one of the
other base classes of the most derived object (1.8).
I interpret the above paragraph as saying the virtual functions called will not be in any derived class. This makes sense because at this point in the execution phase any constructor in a derived class will not have begun execution.
Additionally part 1 places a restriction that use of non-static members should occur after the construction begins. In your example the members are being invoked after the construction begins, so you're not violating part 1:
1 For an object with a non-trivial constructor, referring to any
non-static member or base class of the object before the constructor
begins execution results in undefined behavior.
This code is completely legal. You can call methods
in the class constructor.
All constants (from the initialization list) are already initialized and all base class constructors are called.
However, You should not call virtual methods in the constructor. See Scott Meyers explanation for this restriction.
The thing to think about is, which parts of the object are constructed at the time when you call show()?
Since you call show() from within your constructor's body (and not e.g. from within the constructor's initializer list) you can rest assured that all of the A object's member variables have already been constructed (since that happens before the constructor body is executed).
What might trip you up would be if show() was a virtual method, and A::A() was being called from the constructor of a subclass of A. In that case, you might want show() to call B::show(), but that won't happen because the vtable for B hasn't been set up yet (you would end up calling A::show() instead, or crashing the program if A::show() was a pure-virtual method)
You are calling a function in an partially constructed object, which may result in erroneous behavior if such function deals with class members and such. I am not sure whether its invoking undefined behaviour or not, but I don't think its a good practice. And the situation gets worse with inheritance and virtual functions!
In your example, show could be declared static and there will be no risk in calling it.
Consider a class as 2 separate parts: The object containing fields (variables) and the methods (functions). The methods of a given class exist independent of any particular instance, so it can be called at any time by a valid instance, even mid-construction.
The fields are "created" when the object is instantiated, before the constructor is run. However, they have no values set to them. So, if your constructor calls any methods BEFORE the fields are initialised to sensible values, then you're going to experience some undefined behaviour.
Whenever possible, if you must call a method inside a constructor, be sure to initialise as many fields as possible to sensible values.
my doubt is that when i am creating an object using constructor then how i am able to call object function while object is not fully constructed?
what happens in your example is fine, as long as you initialize where you are supposed to (the initialization list). you are using static dispatch on an object which has initialized members (specifically, A has no such variables to initialize).
what then is invalid?
not initializing your members correctly, or using them before they are really initialized. favor the initialization list without using this.
using dynamic dispatch from within your constructor's body (or initializer). your object is not fully constructed.
unusually, you could also attempt to typecast it to a subclass from the constructor.