简体   繁体   中英

Get address of base object from derived object

I'm getting a very confusing error in my program. I think I may have two different objects of the same class where I thought I had the same object. It is confusing because I am dealing with a very large framework where it is not simple to obtain a pointer to the object I need.

My question is, if I have a class Derived which in inherits from Base, and I have a pointer to a Derived object, how can I get the address of the Base object from the derived object? I am working with the source code of the Base Class and am printing out the address of "this" in Base. In another part of my code a retrieve a pointer to a Derived. I need to be able to print the address of the Base object via my Derived object to determine whether I have a pointer to the particular Derived object I need.

I may have a great misunderstanding of how the addresses work in C++ in inheritance. Perhaps their is only one object, not a base object linked to a derived object?

Thank you very much

Edit: The reason I want to do this is purely for debugging. The problem is that the code base I'm using does not contain many interfaces or protected members, so I am having to edit the source code to access a certain piece of information. However, my program crashes when I call a method I added to the Base class using a specific Derived pointer. I need to be able to print the address of the base object in this case so that I can determine whether this is the correct object or whether I am getting this error because I actually have a pointer to the wrong object. I realize I can add code to the derived class to cause it to print its address, but I was just wondering if it was possible to get the address without editing the source code any more. Thanks

Going from a pointer to derived class to a pointer to a base class is easy:

Derived * derived_ptr = < some pointer >;
Base * base_ptr = derived_ptr;

If you want to be pedantic, you can use static_cast on the right hand side of the assignment:

Base * base_ptr = static_cast<Base*>(derived_ptr);

Going from a pointer to a base class to a pointer to a derived class uses dynamic_cast :

Derived * derived_ptr = dynamic_cast<Derived*>(base_ptr);

However, this won't always work. You need to have run-time typeid enabled and the base class needs to have at least one virtual method.

Before you go doing this, why do you need to go from a base pointer to a derived pointer? That is a clue that you may need to rethink your design.

There is only one object, it is composed of a Base and a Derived- that is, the Base is put into memory right next to the Derived, in most implementations. That means that the Base* is not the same as Derived* in the general case, but they will be very close.

Now, you can trivially obtain the Base* from the Derived*, the cast is implicit, but you can also make it explicit:

Derived* dptr = ...;
Base* ptr = dptr;

However, there is nothing stopping a single derived object from containing multiple Base objects. Usually this is not the case, but it can happen. That means that you cannot compare Base pointers and expect to know if you are dealing with the same object, only the same Base subobject.

In the simple case of single inheritance, with most compilers:

If you've got a pointer to the derived class, then that's the same as the pointer to the base class. Both pointers have the same value and point to the same memory address.

In memory, if you create an instance of a derived class, it will be laid out as the members of the base object, followed by the members of the derived object. The base class members form part of the derived object.

class Base
{
   int b;
};

class Derived : public Base
{
   int d;
};

In memory, say the Derived pointer is 0400. Then:

0400 byte 1 of b
0401 byte 2 of b
0402 byte 3 of b
0403 byte 4 of b
0404 byte 1 of d
0405 byte 2 of d
0406 byte 3 of d
0407 byte 4 of d

The derived object consists of the base members and derived's own members, and the address of both of these starts at 0400.

It just so happens, that at 0400, the base object part of derived is located. So, base and derived have the same address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM