荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Dreamer (我与萤火虫), 信区: SoftDev
标  题: 【C++】[FAQ]为何空类的大小不是零?
发信站: 荔园晨风BBS站 (Mon Jun  7 21:01:50 2004), 站内信件


Q: 为何空类的大小不是零?
A: 为了确保两个不同对象的地址不同,必须如此。也正因为如此,new返回的指针
总是指向不同的单个对象。我们还是来看代码吧:
class Empty { };

void f()
{
Empty a, b;
if (&a == &b) cout << "impossible: report error to compiler supplier";

Empty* p1 = new Empty;
Empty* p2 = new Empty;
if (p1 == p2) cout << "impossible: report error to compiler supplier";
}


另外,C++中有一条有趣的规则——空基类并不需要另外一个字节来表示:
struct X : Empty {
int a;
// ...
};

void f(X* p)
{
void* p1 = p;
void* p2 = &p->a;
if (p1 == p2) cout << "nice: good optimizer";
}


如果上述代码中p1和p2相等,那么说明编译器作了优化。这样的优化是安全的,而
且非常有用。它允许程序员用空类来表示非常简单的概念,而不需为此付出额外的
(空间)代价。一些现代编译器提供了这种“虚基类优化”功能。
[译注:在C++的标准库中大量使用了“定义空类”的技术;一个空类看似什么都不
做,但实则类名即昭示了“类型”信息——而且这个类型信息和RTTI中typeid()返
回的东东不同,并不是只有“让程序员阅读”的价值,而是可以让编译器处理的。
在iterator的实作中,为了达到最佳效率,并提供确切语义,需要针对类类型、指
针类型、常指针类型等提供iterator操作的不同重载版本。这就需要倚重一种称为
“iterator traits”的技术。而iterator traits的实作代码就是通过定义一系列
空类并建立继承体系而达到目的的。SGI的STL实作更是将traits技术推至极至:不
但有iterator traits,还有type traits。Type traits同样是为了达到最高效率
而引入的——它提供了这样的信息:在分配/释放/拷贝对象时是否有必要付出调用
构造函数和析构函数的开销。如果编译器没有“虚基类优化”功能,那么traits技
术就会引入新的额外开销;而具有这种优化功能的编译器可以使traits代码真正在
效率上“趋于完美”——这可真是一件值得庆祝的事 :O) ]





--
如果你真的爱萤火虫,你就不应该将她困在瓶子里;
如果你真的爱萤火虫,你应该放开她,让她在天空中自由自在地飞!
虽然你会不舍得她,但是最终你就会明白这样你才真正拥有了她!

※ 修改:·Dreamer 於 Jun  8 13:18:17 修改本文·[FROM: 192.168.0.223]
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.223]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店