简体   繁体   English

保证C ++中基类的地址?

[英]Guarantees on address of baseclass in C++?

In C struct's, I'm guaranteed that: 在C struct中,我保证:

struct Foo { ... };
struct Bar {
  Foo foo;
  ...
}
Bar bar;
assert(&bar == &(bar.foo));

Now, in C++, if I have: 现在,在C ++中,如果我有:

class Foo { ... };
class Bar: public Foo, public Other crap ... {
  ...
}

Bar bar;
assert(&bar == (Foo*) (&bar)); // is this guaranteed?

If so, can you give me a reference (like "The C++ Programming Language, page xyz")? 如果是这样,你能给我一个参考(如“The C ++ Programming Language,page xyz”)吗?

Thanks! 谢谢!

There is no guarantee. 没有保证。 From the C++03 standard (10/3, class.derived): 从C ++ 03标准(10/3,class.derived):

The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified. 未指定在最派生对象(1.8)中分配基类子对象的顺序。

Even though layout for base classes is not guaranteed in the way you seem to have been thinking (and even though there are more guarantees for members), this is guaranteed: 即使基本类的布局不能保证你想象的方式(即使成员有更多的保证),这也是有保证的:

Bar bar;
assert(&bar == (Foo*) (&bar));

Because the cast uses a static_cast (per 5.4) which will convert &bar correctly, and the comparison between pointer-to-base and pointer-to-derived will convert similarly. 因为强制转换使用static_cast(每5.4)将正确转换&bar ,并且指针到base和指向派生的比较将类似地转换。

This, however, would not be guaranteed: 但是,这不能得到保证:

Bar bar;
void* p1 = &bar;
void* p2 = (Foo*)&bar;
assert(p1 == p2); // not guaranteed

I don't imagine it would be, I don't know why it would need to be. 我不认为会是这样,我不知道为什么会这样。

I have a related question. 我有一个相关的问题。

if you have diamond inheritance: 如果你有钻石继承:

class Base(){ virtual void AFunc(){}  };

class A:Base{};
class B:Base{void AFunc(){} }

class Test:A,B{};


Base * b = (Base*)new Test;

b->AFunc();

lets assume that memory structure is Base:A:B:Test, 假设内存结构是Base:A:B:Test,

note at the point of calling, all the compiler knows is the address of the beginning of the object, and AFunc is expecting to be relative to the beginning of the B object, these two addresses won't be the same! 注意,在调用时,所有编译器都知道对象开头的地址,而AFunc期望相对于B对象的开头,这两个地址不一样! so how does it work? 那么它是怎样工作的?

like if b was of type B, the two addresses would be the same... 就像b是B型,这两个地址是相同的......

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

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