【问题标题】:Class inheritance chain and pointers to each of classes类继承链和指向每个类的指针
【发布时间】:2016-09-19 19:30:18
【问题描述】:

所以给出如下简单代码:

class A{
public:
    virtual void foo() const { cout << "foo in A." << endl;}
private:
    int a;
};

class B: public A{int c;};

class C :  public B{
public:
    void foo() const override  {cout << "foo in B." << endl;}
private:
    int a;
    int b;
};

现在,当我创建 C 类型的对象时,我可以想象它在内存中的布局是这样的:

+----------------+
|     C (int)    |
|+--------------+|
||    B (+1)    ||
||+------------+||
|||  A (2int)  |||
||+------------+||
|+--------------+|
+----------------+

所以现在简单的代码:

C objectC;
A* aPtr = &objectC;
B* bPtr = &objectC;
C* cPtr = &objectC;

我希望,即使编译器生成代码,这会使以下表达式返回 true:

(aPtr == bPtr && bPtr == cPtr)

以下表达式应返回 false:

((int)aPtr == (int)bPtr && (int)bPtr == (int)cPtr)

但在我的电脑上它也返回了 true。同样打印出指针的数值后,它们也是一样的。

我的问题是为什么运行程序后没有出现预期的结果?是否有一些 C++ 文档指定在这种情况下指针值的确切行为,或者它更像是依赖于编译器的事情?

【问题讨论】:

  • 谁说(aPtr == bPtr &amp;&amp; bPtr == cPtr) 必须是真的?你观察到了吗?
  • @NathanOliver 当然,在他的示例中,这些指针应该比较相等(在隐式转换为公共基类型之后)
  • “下面的表达式应该返回 false” 为什么?一个C 包括它的B 子对象包括它的A 子对象。只有当多重继承发挥作用时,你才会得到差异。至于文档,是的,请阅读您的系统和编译器使用的 ABI。
  • @NathanOliver 是的,我观察到了
  • 您的示例中没有多重继承

标签: c++ pointers inheritance


【解决方案1】:

对象的布局更有可能与您显示的相反。

+----------------+ +     +
|    A (int)     | |     |
+----------------+ |  B  |
| delta  B (2 int) |     |  C
+------------------+     |
| delta  C (int)         |
+----------------------- +

当编译器使用这样的布局时,aPtrbPtrcPtr 的数值将是相同的。

我还没有听说过任何编译器可以像您建议的那样创建对象布局。我并不是说没有,只是我没听说过。

【讨论】:

  • 能否请您在答案中说明它是否可以像我在问题中建议的那样以及这是否取决于编译器/平台?
  • @DawidPi,请参阅我的更新。这是我能提供的最好的。
猜你喜欢
  • 2016-09-02
  • 1970-01-01
  • 2011-02-11
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 2019-08-31
  • 1970-01-01
相关资源
最近更新 更多