我在两种智能指针之间编写了一个运算符==,并认为我应该进行快速的健全性检查.我对结果感到惊讶……
在下面的代码片段中,f和b的所有变体如何以相同的值结束?
struct Foo { int x; }; struct Bar : public Foo { int y; }; #include <iostream> int main () { Bar bar; Foo * f = &bar; Bar * b = &bar; std :: cout << f << " " << b << " " << (f == b) << "\n"; void * fv = f; void * bv = b; std :: cout << fv << " " << bv << " " << (fv == bv) << "\n"; int fi = reinterpret_cast <int> (f); int bi = reinterpret_cast <int> (b); std :: cout << fi << " " << bi << " " << (fi == bi) << "\n"; }
解决方法
关于基类对象与其子类对象不具有相同地址的唯一时间是涉及多重继承时.
在上面的示例中,内存可能如下所示:
/ --------- \ / | x | > This is the Foo portion of bar This is the whole Bar object < --------- / \ | y | \ ---------
对象的两个视图具有相同的起点,因此指向任一视图的指针将具有相同的值.
在多重继承中,事情变得更加复杂.说你有:
struct Foo1{ int x; }; struct Foo2{ int y; }; struct Bar : public Foo1,public Foo2 { int z; }; Bar bar;
现在记忆必须像这样:
/ --------- \ / | x | > This is the Foo1 portion of bar / --------- / \ This is the whole Bar object < | y | > This is the Foo2 portion of bar \ --------- / \ | z | \ ---------
因此& bar和(Foo1 *)& bar将具有相同的值,而(Foo2 *)& bar将具有不同的值,因为对象的Foo2部分从更高的地址开始.