包括结构和联合在内的 C++ 类通过值来传递和返回。对于 Plain-Old-Data (POD) 类,C++ 编译器需要像 C 编译器一样传递结构。这些类的对象直接进行传递。对于使用了用户定义复制构造函数的类的对象,编译器需要构造对象的副本,将指针传递到副本,并在返回后销毁副本。这些类的对象间接进行传递。编译器也可以选择介于这两个需求之间的类。不过,该选择影响二进制的兼容性,因此编译器对每个类的选择必须保持一致。
对于大多数编译器,直接传递对象可以加快执行速度。这种执行速度的改善对于小值类(例如复数和概率值)来说尤其明显。有时为了改善程序执行效率,您可以设计更可能直接传递而不是间接传递的类。
在兼容模式 (-compat[=4]) 下,如果类具有以下任何一项,则间接进行传递:
用户定义的构造函数
虚函数
虚拟基类
间接传递的基
间接传递的非静态数据成员
否则,类被直接传递。
在标准模式(缺省模式)中,如果类具有以下任何一条,则间接传递该类:
用户定义的复制构造函数
用户定义的析构函数
间接传递的基
间接传递的非静态数据成员
否则,类被直接传递。
尽可能直接传递类:
只要可能,就使用缺省构造函数,尤其是缺省复制构造函数。
尽可能使用缺省析构函数。缺省析构函数不是虚拟的,因此具有缺省析构函数的类通常不是基类。
避免使用虚函数和虚拟基。
C++ 编译器直接传递的类(和联合)与 C 编译器传递结构(或联合)完全相同。不过,C++ 结构和联合在不同的体系结构上进行不同的传递。
表 10–1 在不同体系结构上结构和联合的传递
体系结构 |
说明 |
---|---|
SPARC V7/V8 |
通过在调用方内分配存储并将指针传递到该存储,传递并返回结构和联合。(也就是说,所有的结构和联合都通过引用传递。) |
SPARC V9 |
不超过 16 个字节(32 个字节)的结构在寄存器中传递。通过在调用方内分配存储并将指针传递到该存储,联合和所有其他结构将被传递并返回。(也就是说,小的结构在寄存器中传递,而联合和大的结构通过引用传递。)因此,小值类与基元类具有相同的传递效率。 |
x86 平台 |
结构和联合通过在堆栈上分配空间并将参数复制到堆栈上来传递。通过在调用程序的帧中分配临时对象并将临时对象的地址作为隐式的第一个参数传递,返回结构和联合。 |