引自<http://www.cppblog.com/qinqing1984/archive/2011/07/10/150584.aspx>
我们知道一个空的类,也就是其内部没有非静态数据成员,没有虚指针(包括指向虚函数表和虚基类子对象的指针),它的大小通常为1,当然在某些对齐要求严格系统上可能是另一个数(通常是4),如果空类被继承,那么派生类的大小会怎么样呢?一个支持C++标准和EBO的编译器对此会进行空基类的优化,也就是不给空的基类子对象分配空间,换句话说,空基类子对象的地址和其派生类实例的地址是相同的。从编译器实现的角度来看,需要考虑继承时的不同情况,下图中P表示父类,C表示子类,圆形表示空类,矩形表示非空类。单继承EBO情况如下图所示
优化应用
由于空基类优化技术节省了对象不必要的空间,提高了运行效率,因此成为某些强大技术的基石,基于类型定义类如stl中的binary_function、unary_function、iterator、iterator_traits的实现复用;基于策略类如内存管理、多线程安全同步的实现复用。当某个类存在空类类型的数据成员时,也可考虑借助EBO优化对象布局,例如下
1
template
<
typename T1,typename T2
>
2
class
EBO
3
{
4
private:
5
T1 m_t1;
6
T2 m_t2;
7
}
;
template
<
typename T1,typename T2
>
2
class
EBO3
{4
private:5
T1 m_t1;6
T2 m_t2;7
}
;
1
template
<
typename T1,typename T2
>
2
class
EBO : T1, T2
3
{
4
}
;
template
<
typename T1,typename T2
>
2
class
EBO : T1, T23
{4
}
;
更进一步,如果T1或T2为非类类型,如基本内建类型、函数指针等;或T1和T2类型相同时,则直接继承它们会导致编译错误,怎么办呢?这时可以添加一个中间层来解决,代码如下
1
template
<
typename T1,typename T2,
bool
isSame,
bool
isFirstEmpty,
bool
isSecondEmpty
>
2
class
EBO_IMPL;
3
4
template
<
typename T1,typename T2
>
5
class
EBO_IMPL
<
T1,T2,
false
,
false
,
false
>
6
{
7
T1 m_t1;
8
T2 m_t2;
9
}
;
10
11
template
<
typename T1,typename T2
>
12
class
EBO_IMPL
<
T1,T2,
false
,
true
,
true
>
: T1,T2
13
{
14
}
;
15
16
template
<
typename T1,typename T2
>
17
class
EBO_IMPL
<
T1,T2,
false
,
true
,
false
>
: T1
18
{
19
T2 m_t2;
20
}
;
21
22
template
<
typename T1,typename T2
>
23
class
EBO_IMPL
<
T1,T2,
false
,
false
,
true
>
: T2
24
{
25
T1 m_t1;
26
}
;
27
28
template
<
typename T1,typename T2
>
29
class
EBO_IMPL
<
T1,T2,
true
,
false
,
false
>
30
{
31
T1 m_t1;
32
T2 m_t2;
33
}
;
34
35
template
<
typename T1,typename T2
>
36
class
EBO_IMPL
<
T1,T2,
true
,
true
,
true
>
: T1
37
{
38
T2 m_t2;
39
}
;
40
41
template
<
typename T1,typename T2
>
42
class
EBO : EBO_IMPL
<
T1,T2,boost::is_same
<
T1,T2
>
::value,boost::is_empty
<
T1
>
::value,boost::is_empty
<
T2
>
::value
>
43
{
44
}
;
template
<
typename T1,typename T2,
bool
isSame,
bool
isFirstEmpty,
bool
isSecondEmpty
>
2
class
EBO_IMPL;3

4
template
<
typename T1,typename T2
>
5
class
EBO_IMPL
<
T1,T2,
false
,
false
,
false
>
6
{7
T1 m_t1;8
T2 m_t2;9
}
;10

11
template
<
typename T1,typename T2
>
12
class
EBO_IMPL
<
T1,T2,
false
,
true
,
true
>
: T1,T213
{14
}
;15

16
template
<
typename T1,typename T2
>
17
class
EBO_IMPL
<
T1,T2,
false
,
true
,
false
>
: T118
{19
T2 m_t2;20
}
;21

22
template
<
typename T1,typename T2
>
23
class
EBO_IMPL
<
T1,T2,
false
,
false
,
true
>
: T224
{25
T1 m_t1;26
}
;27

28
template
<
typename T1,typename T2
>
29
class
EBO_IMPL
<
T1,T2,
true
,
false
,
false
>
30
{31
T1 m_t1;32
T2 m_t2;33
}
;34

35
template
<
typename T1,typename T2
>
36
class
EBO_IMPL
<
T1,T2,
true
,
true
,
true
>
: T137
{38
T2 m_t2;39
}
;40

41
template
<
typename T1,typename T2
>
42
class
EBO : EBO_IMPL
<
T1,T2,boost::is_same
<
T1,T2
>
::value,boost::is_empty
<
T1
>
::value,boost::is_empty
<
T2
>
::value
>
43
{44
}
;
1
template
<
typename T1,typename T2
>
2
class
EBO: boost::compressed_pair
<
T1,T2
>
3
{
4
}
;
template
<
typename T1,typename T2
>
2
class
EBO: boost::compressed_pair
<
T1,T2
>
3
{4
}
;
257

被折叠的 条评论
为什么被折叠?



