The Most Difficult Q in C++

Started by
12 comments, last by SiCrane 17 years, 10 months ago
Here is the most ever hardest issue in C++. How to make a virtual call inside a constructor, forcing the the correct virtual function to be called withing the constructor. I tried a solution but it did not work, to wrap the virtual function inside a local non-virtual function and call it instead. IT NOT WORK LIKE THAT! How?
Advertisement
You don't. The language was designed to specifically prevent that kind of behavior.
Variables in derived classes will not be initialised while the base constructor is running, so this would be dangerous to do.

class Base{    int x;public:    Base()    {       x = foo();    }    virtual int foo();};class Derived : public Base{   int *somePointer;   Derived() : somePointer( new int(0) )   {   }   virtual int foo()   {       return *somePointer;   }  };


In this example, if Derived::foo() was called from the Base constructor, the most likely result would be a segfault at best, as somepointer would not be pointing anywhere in particulars.
Anyone, please correct me if I'm wrong, but here goes;

Virtual functions are hidden pointers; you basically ask 'give me a pointer to...' when calling a virtual function and then that function gets excecuted.
In derived classes, the data member for such a refering pointer is overwritten with a pointer to the derived class' appropriate function. In the constructor of a base class, nothing is known of derived classes. Therefore, the pointers of the virtual members are not yet overwritten. You just get the base class' member.

It's actually quite handy and safe.
--Jeroen Stout - WebsiteCreator of-Divided
You should read this:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.6
Quote:Original post by The Parrot
Anyone, please correct me if I'm wrong, but here goes;

Virtual functions are hidden pointers; you basically ask 'give me a pointer to...' when calling a virtual function and then that function gets excecuted.
In derived classes, the data member for such a refering pointer is overwritten with a pointer to the derived class' appropriate function. In the constructor of a base class, nothing is known of derived classes. Therefore, the pointers of the virtual members are not yet overwritten. You just get the base class' member.

It's actually quite handy and safe.


Yes, but that isnt what the OP desired. The OP wanted the derived classes function called from the base class ctor.
couldn't you do part of the calculations in the base class constructor, then call the function when the derived class constructor executes?
Quote:
Anyone, please correct me if I'm wrong, but here goes;

Virtual functions are hidden pointers; you basically ask 'give me a pointer to...' when calling a virtual function and then that function gets excecuted.
In derived classes, the data member for such a refering pointer is overwritten with a pointer to the derived class' appropriate function. In the constructor of a base class, nothing is known of derived classes. Therefore, the pointers of the virtual members are not yet overwritten. You just get the base class' member.

It's actually quite handy and safe.


Almost.

Each instance of a class has only one pointer, to a VTable instance. The VTable instance holds the pointers to the virtual functions. IIRC, the VTable pointer isn't set until the end of construction. So when you call a virtual function you actually call obj.vtable->func_entry_N();
Quote:Original post by rip-off
Variables in derived classes will not be initialised while the base constructor is running, so this would be dangerous to do.

*** Source Snippet Removed ***

In this example, if Derived::foo() was called from the Base constructor, the most likely result would be a segfault at best, as somepointer would not be pointing anywhere in particulars.


Have you actually tried this? It doesn't work, and will call Base::foo() instead (and produce a link-time error since you haven't provided an implementation for it). The v-table pointer is setup in the construct of Derived, so when the constructor of Base is running the vtable still points to the functions in Base.

As SiCrane said, you don't. I believe it's actually impossible to do since you cannot take a pointer to the actual Derived::foo (this will return a pointer to a function that does the v-table lookup since foo() is a virtual rather than a pointer to the function itself), so even when trying to take a pointer to the function and reinterpret-casting this to Derived* it still calls Base::foo.

Quote:Original post by Skarsha
IIRC, the VTable pointer isn't set until the end of construction.


It actually happens at the start of each constructor in the hierachy, so when the Base constructor is called this's vtable pointer is set to Base's vtable. Likewise when the Derived constructor is called. This ensures that if you call a virtual inside a constructor that the correct function is called up to that point in the construction.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Why do you think you want to do this? Please post the relevant code.

This topic is closed to new replies.

Advertisement