最近遇到了一个诡异的问题, 数组的数据不对, 最后发现是两个类型的大小不一样导致的.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class alloc { public : void * operator new ( size_t n){...} void operator delete ( void * p) {...} }; class alloc2 { public : void * operator new ( size_t n){...} void operator delete ( void * p) {...} }; class DualQuaterion : public class alloc {...}; //override base with different allocation strategy class BoneDQ : public dualquaterion, public class alloc2 { public : using alloc2::operator new ; using alloc2::operator delete ; }; |
两个地方使用的数组类型不一样, 导致数据错误.也就是sizeof(BoneDQ) != sizeof(DualQuaternion).
这是VS2012下的结果, 换用GCC, 两个类型大小一样.
这个真的没有想到.
最后查到问题在这里:
http://en.cppreference.com/w/cpp/language/ebo
上面说的基本限制: 如果同时有连续两个一样的子对象, 那么这两个对象地址不一样(C++标准规定), 导致empty base被阻止.
但跟我遇到的问题仍然不一样.
但是下面又提到,
1
2
|
Empty base optimization is required for StandardLayoutTypes in order to maintain the requirement that the pointer to a standard-layout object, converted using reinterpret_cast, points to its initial member, which is why one of the requirements for a standard layout type is "has no base classes with non-static data members and has no base classes of the same type as the first non-static data member". (since C++11) |
也就是说, 只有C++11以后才要求empty base optimization是必须的. 所以VS2012的处理也是正确的.