Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
740 views
in Technique[技术] by (71.8m points)

c++ - Two questions related to virtual functions

I was reading this articles , was at this heading Inheritance of Base-class vPtrs , but couldn't understand what did he mean in this para :

"However, due to multiple inheritance, a class may indirectly inherit from many classes. If we decide to merge the vtables of all the base classes into one, the vtable may become very big. To avoid this, instead of discarding the vPtrs and vtables of all base classes and merging all vtables into one, the compiler only does it to all the FIRST base classes, and retains the vPtrs and vtables of all the subsequent base classes and their base classes."

In other words, in an object’s memory footprint, you can find the vPtrs of all its base classes all through the hierarchy, except for all the “first-borns”. "

Can anyone please explain this para in simple understandable form.

Another question ,please have look at this answer : Follow this answer

now code of interest (*(foo)((void**)(((void**)(&a))[0]))[1])(); , can anyone tell what is going on? , specially why does this doing exactly in c++(void**)(&a) . i know this is casting but &a returns the address of vptr (in the above question link 2) whose type is void* .

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Virtual function calls are commonly implemented using a virtual method table. Compilers typically create one such table for each class in your program, and give each object a pointer to the virtual table that corresponds to its class when the object is instantiated (this pointer is referred to as vptr). This way, the object "knows" exactly which function to call when you call a virtual method regardless of its static type.

As I mentioned above, normally each class gets its own virtual method table. The paragraph you cite says that if a class derives from e.g. 5 base classes, each of which also derives from 5 other classes, then the virtual table for this class should end up being a merged version of all 25 virtual tables of the base classes. This would be kind of wasteful, so the compiler might decide to only merge the 5 virtual tables from the "immediate" base classes into the derived class's virtual table, and keep the vptrs to the other 20 virtual tables stored as a hidden member inside the class (which would now have 21 vptrs total).

The benefit in doing this is that you don't need to reserve memory repeating the same information every time a class with a virtual table is derived from. The downside is that you complicate the implementation (e.g. when calling a virtual method, the compiler now has to somehow figure out which one of the vptrs points to the table that tells it which method to call).

Regarding the second question, I 'm not sure what exactly you are asking. This code assumes that the vptr is the very first item in the memory layout of object of that class (which is practically true often, but a horrible hack since nowhere does it say that virtual methods are even implemented using a virtual table; there might not even be a vptr), fetches the second item from the table (which is a pointer to a member function of the class) and runs it.

Expect fireworks if even the slightest thing goes wrong (e.g.: there was no vptr, the vptr's structure is not what the person who wrote the code expected, a later version of the compiler decides to change how it stores the virtual table, the method pointed to has a different signature, etc etc etc).

Update (addressing the comments):

Let's say we have

class Child : Mom, Dad {};

class Mom : GrandMom1, GrandDad1 {};

class Dad : GrandMom2, GrandDad2 {};

In this case, Mom and Dad are the immediate base classes ("first-born", but the term is misleading).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...