| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|||||||
| Visual C++ Programming Ask questions about Windows programming with Visual C++ and help others by answering their questions. |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
[RESOLVED] calculating Offset of class
See the code snippet below:
//=========================================== class Base1 { public: virtual void f() { } }; class Base2 { public: virtual void f() { } }; class Base3 { public: virtual void f() { } }; class Drive : public Base1, public Base2, public Base3 { }; #define _ATL_PACKING 8 #define offsetofclass(base, derived) \ ((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING) int main() { cout << offsetofclass(Base1, Drive) << endl; cout << offsetofclass(Base2, Drive) << endl; cout << offsetofclass(Base3, Drive) << endl; return 0; } //============================================== //output is: //0 //4 //8 I really don't understand that how the macro calculates the offset. Please describe it in detail. Furthermore, from MSDN, I don't get much about static_cast or other cast types. Does it play the main role here? What about replacing static_cast with reinterpret_cast or dynamic_cast? Please clear them. Any help would be highly appreciated. Thank you. |
|
#2
|
||||
|
||||
|
Re: calculating Offset of class
First you need to be familiar with how your class is layed out in compiled code. Sans multiple inheritance, the first compiler-supplied member of your class is a pointer to the v-table. A pointer to an instance of your class will contain the location in memory where the instance's pointer to the v-table sits. (Though that is compiler dependent.)
With multiple inheritance, your class has multiple v-table pointers because each base class implies a v-table different from that of the others. These pointers are listed one-after-another at the start of your class. A pointer to your derived class will have the same memory address as the first of those v-table pointers. However, if you cast your pointer to one of its bases, the address will change to the place in memory where the pointer to that class's v-table is stored. Now for the macro. The _ATL_PACKING defintion is somewhat arbitrary. It could probably be any number divisible by 4 and should probably be changed to sizeof(void *) to be compatible with 64-bit systems. The first step of the macro Code:
(derived*)_ATL_PACKING Code:
static_cast<base *>() Code:
(DWORD) Code:
-_ATL_PACKING * reinterpret_cast is for casting one kind of pointer into another * dynamic_cast only works if RTTI is turned on and will attempt the cast of a base type to a derived type * static_cast is basically a general cast, but is much safer than a C-Style cast * const_cast is usually used as a band-aid in poorly-written code (where member functions which were not declared const but should have been) which needs to use better-written code which has used const appropriately. const_cast is also used to remove "volatile". * C-Style cast (used twice in the macro) weakens static analysis but is sometimes necessary (as in the macro) Hope this helps Last edited by GeoRanger; November 26th, 2009 at 12:19 AM. Reason: Forgot to mention cost_cast |
|
#3
|
|||
|
|||
|
Re: calculating Offset of class
Thank you very much for your support. Now I got the idea behind that macro.
|
![]() |
| Bookmarks |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|