应该尽可能使用前向声明而不是包含吗?
不,明确的前向声明不应视为一般准则。前向声明本质上是复制和粘贴或拼写错误的代码,如果发现其中的错误,则需要在使用前向声明的所有位置进行修复。这可能容易出错。
为了避免“转发”声明与其定义之间的不匹配,请将声明放在头文件中,并将该头文件包括在定义文件和使用声明的源文件中。
但是,在这种特殊情况下,仅前向声明一个不透明的类,可以使用此前向声明,但是一般来说,“尽可能使用前向声明而不是包含”,例如该线程的标题可以冒险。
以下是有关前向声明的“无形风险”的一些示例(无形风险=编译器或链接器未检测到的声明不匹配):
下面的示例说明了这一点,例如,两个危险的数据以及函数的前向声明:
文件ac:
#include <iostream>
char data[128][1024];
extern "C" void function(short truncated, const char* forgotten) {
std::cout << "truncated=" << std::hex << truncated
<< ", forgotten=\"" << forgotten << "\"\n";
}
文件密送:
#include <iostream>
extern char data[1280][1024];
extern "C" void function(int tooLarge);
int main() {
function(0x1234abcd);
std::cout << "accessing data[1270][1023]\n";
return (int) data[1270][1023];
}
使用g ++ 4.7.1编译程序:
> g++ -Wall -pedantic -ansi a.c b.c
注意:无形的危险,因为g ++不会提供编译器或链接器错误/警告。
注意:由于c ++名称修改,省略extern "C"
会导致链接错误function()
。
运行程序:
> ./a.out
truncated=abcd, forgotten="♀♥♂☺☻"
accessing data[1270][1023]
Segmentation fault