Jump to content
  • Advertisement
Sign in to follow this  
quaker

The Most Difficult Q in C++

This topic is 4393 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
couldn't you do part of the calculations in the base class constructor, then call the function when the derived class constructor executes?

Share this post


Link to post
Share on other sites
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();

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!