This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling virtual method in base class constructor
Calling virtual functions inside constructors
How can I call a protected virtual method from a constructor in C++?
class Foo
{
Foo(){
printStuff(); // have also tried this->printStuff()
}
protected:
virtual void printStuff() {}
}
class ExtendedFoo : public Foo {
protected:
virtual void printStuff() { cout << "Stuff" << endl;}
}
...
ExtendedFoo exFoo; // should print "Stuff"
There's no problem in calling a protected function from the constructor - just do it. However, what you seem to be wanting is to call into a concrete derived class' implementation of it, e.g., ExtendedFoo's, since it's virtual - right? That's a no-go, since inside the Foo constructor, the object being created is still of type Foo, not ExtendedFoo, so no virtual dispatch can take place. If the protected function isn't pure virtual, the Foo implementation is called, i.e., the constructor will call the class' own implementation.
Consider that when your base constructor is called, your actual constructor still does not, so you object is not completely formed.
If your object isn't yet formed, you can't expect it to act correctly.
Please read this:
Never Call Virtual Functions during Construction or Destruction.
[10.7] Should you use the this pointer in the constructor?
You can, but you will get Foo's implementation because ExtendedFoo's not been constructed. This is defined.
Similar problem: C++ design pattern: multiple ways to load file
Answer deprecated after question change:
If it is protected in ExtendedFoo, you can not call it from outside of ExtendedFoo. The line...
exFoo.printStuff();
violated the function's protection level.
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr129.htm
Related
This question already has answers here:
Pure virtual function with implementation
(10 answers)
Closed 3 years ago.
Pure virtual functions (when we set = 0) can also have a function body.
What is the use to provide a function body for pure virtual functions, if they are not going to be called at all?
Your assumption that pure virtual function cannot be called is absolutely incorrect. When a function is declared pure virtual, it simply means that this function cannot get called dynamically, through a virtual dispatch mechanism. Yet, this very same function can easily be called statically, non-virtually, directly (without virtual dispatch).
In C++ language a non-virtual call to a virtual function is performed when a qualified name of the function is used in the call, i.e. when the function name specified in the call has the <class name>::<function name> form.
For example
struct S
{
virtual void foo() = 0;
};
void S::foo()
{
// body for pure virtual function `S::foo`
}
struct D : S
{
void foo()
{
S::foo();
// Non-virtual call to `S::foo` from derived class
this->S::foo();
// Alternative syntax to perform the same non-virtual call
// to `S::foo` from derived class
}
};
int main()
{
D d;
d.S::foo();
// Another non-virtual call to `S::foo`
}
"Effective C++" Meyers mentions a
reason for a pure virtual function to
have a body: Derived classes that
implement this pure virtual function
may call this implementation smwhere
in their code. If part of the code of
two different derived classes is
similar then it makes sense to move it
up in the hierarchy, even if the
function should be pure virtual.
see here.
For most pure virtual functions, you'd be right. However, for a pure virtual destructor, it's actually important to define a corresponding destructor implementation:
The "pure virtual" is to require derived classes to implement their destructor.
Your base class destructor implementation is so that the derived class destructors can successfully "chain up" afterwards.
I have two questions and the answers I found here didn't totally satisfy me:
Why declaring a constructor as virtual is meaningless?
What happens when I call a virtual function from a constructor? Is the virtual table used too?
Why declaring a constructor as virtual is meaningless?
Before the constructor is executed, the object does not exists, so there is no such thing as an override.
What happens when I call a virtual function from a constructor? Is the virtual table used too?
It can. In most cases, if the call is directly performed from the constructor the compiler can skip the dynamic dispatch, as it knows what the final overrider is at this point. But it need not perform that optimization, and even if it can do that in the constructor directly, it cannot do it if you call a non-virtual function that in turn calls the virtual function. Because the non-virtual function might be called for objects of derived types it must use the virtual dispatch mechanism.
When calling a constructor, the actual type of the (not yet existing) object is known for very sure. So calling a constructor will never be indirect. (Only virtual functions are called indirectly when called via a pointer / reference.)
BaseClass *x = new SubClass();
Calling a virtual function in a constructor doesn't do what you might expect. As the subclass hasn't been initialized yet, the virtual function on the final class can't be called (the v-table currently points to the class of the constructor currently being executed).
class BaseClass {
BaseClass() {
call();
}
virtual void call() {
std::cout << "BaseClass!";
}
};
class SubClass : public BaseClass {
SubClass() : BaseClass()
{
}
void call() {
std::cout << "SubClass!";
}
};
http://ideone.com/9aQVIc
Why declaring a constructor as virtual is meaningless.
When the constructor is invoked the virtual table would not be available in the memory. Declaring something virtual in C++ means that it can be overridden by a sub-class of the current class, however the constructor is called when the objected is created, at that time you can not be creating a sub-class of the class you must be creating the class so there would never be any need to declare a constructor virtual. Therefore, there is no such a thing as virtual constructor in C++.
What happens when I call a virtual function from a constructor? Is the virtual table used too
See C++ FAQ link about detailed explanation of this question.
I have some code where I really want to call a virtual method from a constructor. I know this is considered unsafe, and I know enough about object construction to also understand why. I also am not experiencing these problems. Currently my code is working and I think it should be fine, but I want to make sure.
Here is what I am doing:
I have some class hierarchy and there is a normal public function which just forwards to a private virtual method, as usual. However I do want to call this public method upon construction of my objects, because it is filling all data into the object. I will be absolutely sure that this virtual call comes from the leaf class, because using this virtual method from any other part of the class hierarchy simply does not make sense at all.
So in my opinion the object creation should be finished once I am doing the virtual call and everything should be fine. Is there still anything that could go wrong? I guess I'll have to mark this part of the logic with some big comments to explain why this logic should never ever be moved to any of the base clases, even though it looks like it could be moved. But other than stupidity of other programmers I should be fine, shouldn't I?
It is absolutely safe to call any non-abstract virtual function in the constructor or the destructor! However, its behavior may be confusing as it may not do what is expected. While the constructor of a class is executed, the static and dynamic type of the object is the type of the constructor. That is, the virtual function will never be dispatched to the override of a further derived class. Other than that, virtual dispatch actually works: e.g. when calling a virtual function via a base class pointer or reference correctly dispatches to the override in the class being currently constructor or destructed. For example (probably riddled with typos as I currently can't this code):
#include <iostream>
struct A {
virtual ~A() {}
virtual void f() { std::cout << "A::f()\n"; }
void g() { this->f(); }
};
struct B: A {
B() { this->g(); } // this prints 'B::f()'
void f() { std::cout << "B::f()\n"; }
};
struct C: B {
void f() { std::cout << "C::f()\n"; } // not called from B::B()
};
int main() {
C c;
}
That is, you can call a virtual function, directly or indirectly, in the constructor or a destructor of a class if you don't want the virtual function to be dispatched to a further derived function. You can even do this is virtual function is abstract in the given class as long as it is defined. However, having an undefined abstract function being dispatched to will cause a run-time error.
When a constructor is called, the class is set up to be an instance of that class but not the derived class. You cannot call into a virtual function of a derived class from a base constructor. By the time you get to the constructor of the most derived class, all of the virtual functions should be safe to call.
If you wish to ensure that someone can't make an incorrect call, define the virtual function in the base class and have it assert and/or throw an exception when it is called.
The rule isn't so much that you need to be in a leaf class as to realize that when you make a member call from Foo::Foo(..), the object is exactly a Foo, even if it's on its way to being a Bar (assuming Foo is derived from Bar and you're constructing a Bar instance). That's 100% reliable.
Otherwise, the fact that the member is virtual isn't all that significant. There are other pitfalls that happen just as well with non-virtual functions: if you were to call a virtual or non-virtual method that assumed the object was completely constructed but called it within the constructor before that was the case, you'd also have problems. These are just hard cases to pin down because not only must the function you call be okay, all the functions it calls must be okay.
It doesn't sound like you have a problem, it's just one of those places prone for errors to crop up.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ virtual function from constructor
Calling virtual functions inside constructors
This question was asked in interview .
I guess I had answered the 1st part correctly but not sure about the 2nd part. In fact I have no clue about 2nd part.
What output does the following code generate? Why?
What output does it generate if you make A::Foo() a pure virtual function?
When I tried running same question on my compiler with virtual void foo() = 0; it throws
error "undefined reference to `A::Foo()'"
#include <iostream>
using namespace std;
class A
{
public:
A()
{
this->Foo();
}
virtual void Foo()
{
cout << "A::Foo()" << endl;
}
};
class B : public A
{
public:
B()
{
this->Foo();
}
virtual void Foo()
{
cout << "B::Foo()" << endl;
}
};
int main(int, char**)
{
B objectB;
return 0;
}
When you instantiate a B object, the following happens:
B's constructor is called.
First thing, B's constructor calls the base constructor A().
Inside A's constructor, the function call is dispatched to A::foo(), since this has static and dynamic type A* (nothing else makes sense if you think about it); now the A subobject is complete.
Now B's constructor body runs. Here the function call is dispatched to B::foo(). Now the entire B object is complete.
If A::foo() is pure-virtual, step (3) causes undefined behaviour; cf. 10.6/4 in the standard.
(In your case possibly manifesting as a linker error, since the compiler optimizes to resolve the call statically, and the symbol A::foo is not found.)
In the second case you have undefined behavior (calling a pure virtual of class T in a class T constructor), so the output could be anything – if it even compiles.
The main thing to understand is that in C++, the dynamic type of an object is T when an object's T constructor executes.
This makes it safe to call virtual functions from a C++ constructor. You don't get a call down into an uninitialized derived class sub-object. In contrast, in Java and C# (and similar languages) you can easily get that kind of bug, and it's common.
Constructors will be called so that the parents are constructed first, so that there won't be any dependencies on undefined objects. Thus it's A::A followed by B::B. Edit: It's also possible that B's constructor calls A's directly, as Kerrek SB says - the end effect is the same.
In the first case, the output will be "A::Foo()" followed by "B::Foo()". At the time of A's construction B doesn't exist yet, and its virtual functions aren't yet part of the object.
In the second case, you'll be calling a pure virtual function A::Foo which will generate a fault or refuse to compile altogether.
Methods in constructors are dispatched as the dynamic type of the class. A's constructor is calling Foo with dynamic type A. (see AlfP.Steinbach's comment for the correct definition)
If A is an abstract base then the error is because it's trying to call a pure virtual method.
A()
{
this->Foo(); // call A::Foo
}
From Effective C++ by Scott Meyers:
There's a good reason for this seemingly counterintuitive behavior. Because base class constructors execute before derived class constructors, derived class data members have not been initialized when base class constructors run. If virtual functions called during base class construction went down to derived classes, the derived class functions would almost certainly refer to local data members, but those data members would not yet have been initialized. That would be a non-stop ticket to undefined behavior and late-night debugging sessions. Calling down to parts of an object that have not yet been initialized is inherently dangerous, so C++ gives you no way to do it.
Sorry if this is a dupe, I cant find an answer quite right.
I want to call a function from a base class member, and have it resolve to the subclass version. I thought declaring it virtual would do it, but it isn't. Here's my approach:
class GUIWindow
{
public:
GUIWindow()
{
SetupCallbacks();
}
virtual void SetupCallbacks()
{
// This function always called
}
};
class GUIListbox : public GUIWindow
{
public:
void SetupCallbacks()
{
// This never called
}
};
GUIListbox lb; // GUIWindow::SetupCallbacks is called :(
What am I doing wrong?
Many thanks
Si
Never call a virtual function in the constructor.
When you call virtual functions during construction of some class C (i.e. while the constructor of C is active), the virtual mechanism works, but it works in restricted mode. The resolution of the virtual calls in the class hierarchy is limited by the class that is currently being constructed (C). This means that the virtual calls will resolve as if the class C is the "final" class in the hierarchy, as if it has no descendants.
The same is true for destructors.
In your example, you are calling a virtual function from constructor of class GUIWindow. As long as the constructor of GUIWindow is active, its virtual mechanism will work as if there are no other classes derived from GUIWindow. This mechanism will completely ignore the existence of GUIListbox class. This is why the resolution of virtual call "stops" at GUIWindow and calls GUIWindow::SetupCallbacks, as if GUIListbox::SetupCallbacks doesn't exist.
You can read about in in C++ FAQ
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.5
Your derived type is not constructed yet.
Class Cat : Animal
{
//...
};
When you create a create a Cat object the following happens:
Construct Animal
Construct Cat
When your object goes out of scope or gets destroyed via delete if on the heap, the following happens:
Destruct Cat
Destruct Animal
For this reason you should not call virtual functions in your constructor or destructor. You would even have a pure virtual function call if you did not have an implementation in your base class.
You are going to have to:
GUIListbox lb;
lb.SetupCallbacks();
The point of virtual is so that you can do things like:
GuiWindow *lb = new GuiListbox();
lb->SetupCallback();//Gets correctly resolved to GuiListBox's version
The problem is that you are trying to call the virtual function form the constructor. The base class constructor is called before the constructor of the derived class, so the "derived parts" of the object are not created yet when the base classes constructor runs.
The object will behave like an object of the base class type until the base classes constructor is finished and the derived classes constructor starts. This means that calls to virtual functions will not call implementations defined in the derived class, they will just execute the version from the base class.
Also see the C++ FAQ lite for more details and possible workarounds.
The quick answer is that you may have to declare a constructor in GUIListbox which calls SetupCallbacks. The reason is more complicated: because GUIListbox doesn't declare a constructor, when you declare an object of that type the GUIWindow constructor is called. When the GUIWindow constructor is running, the object isn't a GUIListbox yet. From the compiler's perspective, it only becomes a GUIListbox once the (empty) constructor for that class starts. So when the first constructor runs, the methods from GUIWindow are called. IOWs, this doesn't work, and will never work in C++ the way that you want it to.
Here's a reference describing this pitfall in detail: http://www.artima.com/cppsource/nevercall.html.
And here's an explanation from my favorite C++ resource: http://yosefk.com/c++fqa/inheritance-mother.html#fqa-23.5