【问题标题】:Simple inheritance question简单的继承问题
【发布时间】:2011-03-04 22:52:42
【问题描述】:

假设我有以下层次结构:

class A  
{  
 public:  
 A()   
 private:  
 int aa;  
}

class B: public A  
{  
 public:  
 B()   
 private:  
 int bb;  
}

class D: public B  
{  
 public:  
 D()   
 private:  
 int dd;  
}

当我在 main 中输入以下代码时:

D dobj;
std::cout<<"Address of D object: "<<&dobj<<std::endl;

A aobj = static_cast<A>(dobj);
A* aptr = static_cast<A*>(&dobj);

std::cout<<"Address of D object: "<<&dobj<<std::endl;
std::cout<<"Address of aptr object: "<<&aptr<<std::endl;
std::cout<<"Address of A object: "<<&aobj<<std::endl;

其输出为:

Address of dobj object: 0012FF0C
Address of dobj object: 0012FF0C
Address of aptr object: 0012FF18
Address of aobj object: 0012FF14

为什么aptr和aobj的地址不一样??他们不应该是一样的吗??

为什么dobj和aptr的地址不一样??他们不应该也一样吗?

我正在使用 VC++ 在 Windows 上进行编译。

谢谢, 德科斯托。

【问题讨论】:

    标签: c++ casting type-conversion


    【解决方案1】:

    为什么aptr&amp;aobj 不同?

    首先,您打印出错误的指针:&amp;aptr 是“aptr 的地址”,而不是“aptr 指向的对象的地址”。您只需打印 aptr 即可打印“aptr 指向的对象的地址”,这大概是您真正想要做的。

    aptr 是指向dobjA 部分的指针。 aobjdobjA 部分的副本

    aptr&amp;aobj是不同的,因为它们是不同对象的地址。

    【讨论】:

    • @de costo:首先,强制转换是不必要的:您可以将D* 隐式转换为A*,因此您只需说aptr = dptr;。这些指针可能具有相同的值:aptr 将指向D 对象的A 基类部分。如果A 基类部分位于D 对象的开头,则aptr 将与dptr 相同。
    • 我的错!!感谢您指出,但是如果我将它转换为 B 的指针,如下所示: B* bptr = static_cast(&dobj); aptr 和 bptr 的地址是一样的。如果 bptr 指向 D 对象的 B 部分,并且由于 B 基类不位于 D 对象的开头,那么 aptr 和 bptr 不应该不同吗??
    • @de costo:很有可能,B 类像 [A base class][bb member] 一样在内存中布局,D 类像 [B base class][dd member] 一样在内存中布局。这样,给定D x;,以下所有三个都将给出相同的地址:(1)&amp;x,(2)static_cast&lt;B*&gt;(x),和(3)static_cast&lt;A*&gt;(x)。如果您使用 Visual C++(或在大多数其他编译器上)进行编译,那么在您展示的单继承层次结构中,基类应始终位于派生类的开头(最终转换成本更低,并且以这种方式向下继承继承层次结构)。
    • 有什么办法可以找出它们在内存中的排列方式吗?我知道它在不同的操作系统中是不同的,但是这种内存组织有什么通用格式吗??
    猜你喜欢
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多