1

我的程序中出现了一个非常令人困惑的错误。我想我可能有同一个类的两个不同的对象,我认为我有相同的对象。这很令人困惑,因为我正在处理一个非常大的框架,在其中获取指向我需要的对象的指针并不简单。

我的问题是,如果我有一个继承自 Base 的 Derived 类,并且我有一个指向 Derived 对象的指针,我如何从派生对象中获取 Base 对象的地址?我正在使用基类的源代码,并在 Base 中打印出“this”的地址。在我的代码的另一部分中,检索指向 Derived 的指针。我需要能够通过我的 Derived 对象打印 Base 对象的地址,以确定我是否有指向我需要的特定 Derived 对象的指针。

我可能对地址在 C++ 中继承的工作方式有很大的误解。也许它们只是一个对象,而不是链接到派生对象的基础对象?

非常感谢

编辑:我想这样做的原因纯粹是为了调试。问题是我使用的代码库不包含很多接口或受保护的成员,所以我必须编辑源代码才能访问某些信息。但是,当我使用特定的派生指针调用添加到基类的方法时,我的程序崩溃了。在这种情况下,我需要能够打印基础对象的地址,以便我可以确定这是否是正确的对象,或者我是否收到此错误,因为我实际上有一个指向错误对象的指针。我意识到我可以向派生类添加代码以使其打印其地址,但我只是想知道是否可以在不编辑源代码的情况下获取地址。谢谢

4

3 回答 3

5

从派生类的指针到基类的指针很容易:

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

如果您想学究气,可以static_cast在作业的右侧使用:

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

从指向基类的指针到指向派生类的指针使用dynamic_cast

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

但是,这并不总是有效。您需要启用运行时 typeid,并且基类需要至少有一个虚拟方法。

在执行此操作之前,为什么需要从基指针转到派生指针?这是您可能需要重新考虑您的设计的线索。

于 2011-06-18T21:14:51.593 回答
3

只有一个对象,它由 Base 和 Derived 组成——也就是说,在大多数实现中,Base 紧挨着 Derived 放入内存中。这意味着在一般情况下 Base* 与 Derived* 不同,但它们会非常接近。

现在,您可以轻松地从 Derived* 获得 Base*,强制转换是隐式的,但您也可以使其显式:

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

但是,没有什么可以阻止单个派生对象包含多个 Base对象。通常情况并非如此,但它可能会发生。这意味着您无法比较Base指针并期望知道您是否正在处理同一个对象,只有同一Base个子对象。

于 2011-06-18T21:07:15.433 回答
1

在单继承的简单情况下,对于大多数编译器:

如果您有一个指向派生类的指针,那么它与指向基类的指针相同。两个指针具有相同的值并指向相同的内存地址。

在内存中,如果创建派生类的实例,它将被布置为基对象的成员,然后是派生对象的成员。基类成员构成派生对象的一部分。

class Base
{
   int b;
};

class Derived : public Base
{
   int d;
};

在内存中,假设 Derived 指针是 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

派生对象由基成员和派生自己的成员组成,两者的地址都从 0400 开始。

碰巧的是,在 0400,派生的基础对象部分位于。因此,base 和derived 具有相同的地址。

于 2011-06-18T21:27:02.970 回答