繁体   English   中英

C ++指针多继承的乐趣

[英]C++ pointer multi-inheritance fun

我正在编写一些涉及从基本引用计数指针类继承的代码; 并且出现了一些复杂的C ++。 我把它减少如下:

假设我有:

class A{};
class B{};
class C: public A, public B {};

C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;

// does pa point to a valid A object?
// does pb point to a valid B object?

// does pa == pb ?

此外,确实:

// pc == (C*) pa ?
// pc == (C*) pb ?

谢谢!

  • pa指向有效的A对象?
  • pb是否指向有效的B对象?

是的, C*被转换,以便papb指向正确的地址。

  • pa == pb?

不,通常不是。 在同一地址不能有A对象和B对象。

此外,是吗

  • pc ==(C *)pa?
  • pc ==(C *)pb?

强制转换将指针转换回C对象的地址,因此两个等式都为真。

C嵌入AB

class C: public A, public B {};

与C代码非常相似

struct C {
    A self_a;
    B self_b;
};

(B*) &c; 相当于static_cast< B* >( &c )类似于&c.self_b如果你直接使用C.

通常, 您不能依赖指向不同类型的指针,这些指针是可互换的或可比较的。

pc == pa;
pc == pb;

未定义,取决于类结构。

pc == (C*) pa;
pc == (C*) pb;

没关系。

pa == pb;

没有。

他们指向有效的对象吗?

Yes

项目28 C ++ 中指针比较的含义 常识:基本中间编程 )解释了C ++中对象指针的关键:

在C ++中,对象可以有多个有效地址,指针比较不是关于地址的问题。 这是一个关于对象身份的问题。

看看代码:

class A{};
class B{};
class C: public A, public B {};

C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;

class C源自class Aclass B ,因此class C class A既是class A class B 对象C c有3个有效地址: class A class B class Cclass C class B地址。 实现依赖于编译器,因此您不能假设class C的内存布局,它可能是这样的:

 ----------  <- pc (0x7ffe7d10e1e0)
 |        |
 ----------  <- pa (0x7ffe7d10e1e4)
 | A data |
 ----------  <- pb (0x7ffe7d10e1e8)
 | B data |
 ----------
 | C data |
 ----------

在上面的例子中,尽管pcpapb的地址值不相同,但它们都引用相同的对象( c ),因此编译器必须确保pc比较等于papb ,即pc == papc == pb 编译器通过调整被比较的指针之一的值通过适当的偏移量来完成此比较。 例如,

pc == pa

被翻译成:

pc ? ((uintptr_t)pc + 4 == (uintptr_t)pa) : (pa == 0)

除此之外,由于AB没有继承关系,我们无法直接比较papb

对于你的问题:

(1) does pa point to a valid A object?  
(2) does pb point to a valid B object?  
Yes, refer the above diagram. 

(3) pc == (C*) pa ?  
(4) pc == (C*) pb ?  
Yes, No need to add (C*).

(5) does pa == pb ?
No. We can't compare them.

你得到的是记忆中的这样的东西

 ----------
 | A data |
 ----------
 | B data |
 ----------
 | C data |
 ----------

因此,如果您想要整个C对象,您将获得指向内存开头的指针。 如果您只想要A“部分”,那么您将获得相同的地址,因为数据成员所在的地址。 如果你想要B“部分”你得到开头+ sizeof(A)+ sizeof(无论编译器为vtable添加什么)。 因此,在这个例子中,pc!= pb(可能是pc!= pa)但是pa永远不等于pb。

暂无
暂无

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

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