[C++] 前向聲明(forward declaration)


1.前向聲明只是一種“聲明”

2.為什么前向聲明在C++中是必要的

編譯器想要確定沒有拼寫錯誤,並且傳遞給函數的參數也是對的,因此編譯器要求在調用任何函數之前,必須首先看到該函數的聲明。簡而言之,任何變量或函數等,都是要求先聲明再使用。

3.前向聲明和定義之間的區別

函數聲明需要提供返回類型,調用約定,方法名,參數以及參數類型,而定義要求有代碼實現。

4.前向聲明能顯著縮短編譯鏈接時間

通過使用 #include一些含有函數聲明的頭文件, 你可以將函數聲明加到你的當前 .cpp文件或 .h文件中,然而,這會拖慢編譯時間。尤其是如果在.h文件中#include 頭文件時,這是因為,任何#include你寫的.h文件的文件,結局是都將#include你所#include的頭文件,編譯器一下子需要編譯無窮無盡的文件,即使需要調用的實際上只有一兩個函數。
為了避免這種情況,你可以使用前向聲明,也就是在文件頂部給出函數聲明。對於大型項目,使用前向聲明有可能使數小時的編譯時間壓縮為只需要幾分鍾。

5.當兩個定義互相使用對方時,打破循環

除此之外,實現前向聲明可以打破循環。這種情況是,兩個函數試圖互相調用對方。如果出現這種情況,可以#include一個頭文件,但是那個頭文件又試圖#include你目前正在寫的文件,兩個文件互相#include, 可以使用前向聲明解決這個問題。即一個文件使用前向聲明,另一個文件使用 #include。

舉例:

文件Car.h:

// File Car.h
#include "Wheel.h"  // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
    std::vector<Wheel> wheels;
};

但是對於頭文件 Wheel.h, 必須提供Car 的聲明,原因是因為類Wheel含有一個指向Car的指針,但是不能在文件 Wheel.h 中包含Car.h,如果包含,將產生編譯錯誤。如果Wheel.h 包含 Car.h, Car.h 又會包含 Wheel.h, Wheel.h 又會包含Car.h, 如此將陷入不斷的循環中,所以編譯器沒有這樣做,而是引發了一個錯誤。
解決這個問題的方法是聲明Car,不能使用包含:

// File Wheel.h
class Car;     // forward declaration
class Wheel
{
    Car* car;
};

如果類 Wheel 含有方法,這些方法需要調用Car的方法,那么Wheel的方法可以定義在文件Wheel.cpp 中,Wheel.cpp 可以包含Car.h, 但不會導致循環。

6 另一個例子

相對簡單的例子, 兩個文件 main.cpp 和 add.cpp, 使用前向聲明,不包含頭文件,一樣可以編譯通過:

// add.cpp:
int add(int x, int y)
{
    return x + y;
}
// main.cpp:
#include <iostream>
int add(int x, int y); // 前向聲明
int main()
{
    std::cout << "The sum of 3 and 4 is " << add(3, 4) << std::endl;
    return 0;
}

[1] https://stackoverflow.com/questions/4926105/what-is-forward-declaration-in-c
[2] https://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration
[3] https://stackoverflow.com/questions/4757565/what-are-forward-declarations-in-c
————————————————
版權聲明:本文為CSDN博主「2222345345」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/ftell/article/details/80481662

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM