如果一個使用前向聲明,而不是包括在可能的情況?
不,不應將明確的前向聲明視爲一般準則。前向聲明本質上是複製和粘貼的,或者拼寫錯誤的代碼,如果你發現它的錯誤,需要在任何地方使用前向聲明來修復。這可能容易出錯。
爲避免「向前」聲明與其定義之間的不匹配,請將聲明放入頭文件中,並將該頭文件包含在定義聲明和使用聲明的源文件中。
然而,在這種特殊情況下,只有一個不透明的類是前向聲明的,這個前向聲明可能可以使用,但一般來說,「儘可能使用前向聲明而不是include」,就像這個標題一樣線程說,可能是相當危險的。
下面是關於前向聲明(無形風險=聲明不匹配不是由編譯器或連接器檢測)「看不見的風險」的一些示例:表示數據可能是不安全的符號
下面的例子說明了這個,例如,數據的兩個危險向聲明以及函數:
文件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";
}
文件BC:
#include <iostream>
extern char data[1280][1024]; // 1st dimension one decade too large
extern "C" void function(int tooLarge); // Wrong 1st type, omitted 2nd param
int main() {
function(0x1234abcd); // In worst case: - No crash!
std::cout << "accessing data[1270][1023]\n";
return (int) data[1270][1023]; // In best case: - Boom !!!!
}
使用g ++ 4.7.1編譯程序:
> g++ -Wall -pedantic -ansi a.c b.c
注:隱形危險,因爲G ++沒有給出編譯器或鏈接錯誤/警告
注:省略extern "C"
導致對function()
一個鏈接錯誤由於C++名字改編。
運行程序:
> ./a.out
truncated=abcd, forgotten="♀♥♂☺☻"
accessing data[1270][1023]
Segmentation fault
簡單的答案,沒有。 – Nim 2012-03-28 11:20:36
呃 - 這個問題的答案是頂部還是底部? – Mat 2012-03-28 11:21:42
你真正的問題(底部) - AFAIK沒有理由不在這種情況下使用前向聲明... – Nim 2012-03-28 11:22:40