简体   繁体   English

从派生对象获取基础对象的地址

[英]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? 我的问题是,如果我有一个继承自Base的Derived类,并且有一个指向Derived对象的指针,我如何从该派生对象中获取Base对象的地址? I am working with the source code of the Base Class and am printing out the address of "this" in Base. 我正在使用基类的源代码,并在基类中打印出“ this”的地址。 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. 我可能对地址在继承中的C ++工作方式有很大的误解。 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. 但是,当我使用特定的Derived指针调用添加到Base类的方法时,程序崩溃。 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: 如果您想做书呆子,可以在作业的右侧使用static_cast

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 : 从指向基类的指针到派生类的指针使用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. 您需要启用运行时typeid,并且基类至少需要一个虚拟方法。

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. 只有一个对象,它由一个Base和一个Derived组成-也就是说,在大多数实现中,该Base放在Derived旁边的内存中。 That means that the Base* is not the same as Derived* in the general case, but they will be very close. 这意味着在一般情况下,Base *与Derived *不同,但是它们将非常接近。

Now, you can trivially obtain the Base* from the Derived*, the cast is implicit, but you can also make it explicit: 现在,您可以从Derived *轻松获取Base *,强制转换是隐式的,但您也可以使其明确:

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

However, there is nothing stopping a single derived object from containing multiple Base objects. 但是,没有什么可以阻止单个派生对象包含多个 Base对象。 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. 这意味着您无法比较Base指针,并且期望知道您是否在处理同一对象,而仅是同一Base子对象。

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。然后:

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. 派生的对象由基本成员和派生的自身成员组成,这两个对象的地址都始于0400。

It just so happens, that at 0400, the base object part of derived is located. 恰好发生在0400,派生的基础对象部分已定位。 So, base and derived have the same address. 因此,base和derived具有相同的地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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