Function Pointers

I went through an article by Don Clugston on Codeproject. This is a beautiful article and quite famous. In the following code snippet, I found a very clear concept:

class A { public: virtual int Afunc() { return 2; }; }; class B { public: int Bfunc() { return 3; }; }; // C is a single inheritance class, derives only from A class C: public A { public: int Cfunc() { return 4; }; }; // D uses multiple inheritance class D: public A, public B { public: int Dfunc() { return 5; }; }; 

The following paragraph follows the fragment:

Suppose we create a member function pointer for class C. In this example, Afunc and Cfunc are member functions of C, so our member is allowed to point to a function pointer to Afunc or Cfunc. But Afunc needs this pointer, which points to C :: A (which I will name Athis), while Cfunc needs this pointer, which points to C (which I will name Cthis). The authors of the compiler deal with this situation with a trick: they make sure that A is physically stored at the beginning of C. This means that Athis == Cthis. We have only one thing to worry about, and everything is fine with the world.

The only thing I want to understand is the line in BOLD and ITALICS in the paragraph above.

I do not fully understand Afunc needs a pointer to C :: A , and Cfunc needs a pointer to C. It `s naturally.

Any help would be appreciated.

+6
source share
1 answer

By calling a member function in C ++, internally, the instance is passed as the hidden first argument (note that this behavior is strictly determined by the behavior). The C ++ standard does not have the right to talk about this issue, its just a very common way to implement it):

 xf(y); // is treated internally as: f(&x, y); 

This first argument is then accessible using the this pointer.

now Afunc in the example above internally has the signature void Afunc(A* const this) , and CFunc has the internal signature void CFunc(C* const this) .

Please note that the types of arguments are different in both cases, so when you call functions on the same object, you need to pass a different pointer. C ++ solves this by defining an implicit conversion from any derived object to its base object. That is, in the following code:

 C* pc = something; pc->Afunc(); 

This code is processed internally similar to the following (pseudocode):

 C* pc = something; Afunc(static_cast<A*>(pc)); 

This cast is for single inheritance without an operation (that is, you can simply delete it) with the trick mentioned in the quote: object C and its parent object A are stored in the same physical address. An object of type C , which is stored at address x in memory, is physically laid out in such a way that its parent object of type A also stored at address x , followed by all other members that C may have (but in your case it has no members, and sizeof(C) == sizeof(A) ).

+9
source

Source: https://habr.com/ru/post/917869/


All Articles