HOWTO · C++
C++ 中對 Class::Function() 的未定義引用
解決 C++ 中未定義引用的連結器錯誤的簡短教程。
本教程簡要討論了 C++ 程式設計中最常見且同樣嚴重的錯誤之一(即未定義對 Class::Function() 的引用)。
首先,我們將簡要討論在 C++ 中編碼時的不同錯誤。然後,我們將解釋未定義引用錯誤的原因和解決方法。
C++ 中的錯誤型別
與任何其他程式語言一樣,由於多種原因,C++ 程式碼可能會出現錯誤或錯誤。這些錯誤大致分為以下錯誤類別:
語法錯誤是由於違反 C++ 規則或任何語法而發生的錯誤。執行時錯誤是在語法上沒有程式設計問題但在執行時檢測到並導致程式崩潰時發生的錯誤。- 當我們沒有得到我們想要的結果或輸出時,就會發生
邏輯錯誤,這意味著我們的程式邏輯中存在錯誤。 連結器錯誤是程式成功編譯並嘗試將其他一些物件與我們的主物件檔案連結時的錯誤型別,因此不會生成可執行檔案。例如,定義的函式的任何錯誤原型、包含的任何不正確的標頭檔案等。
C++ 中對 Class::Function() 的未定義引用
這是 C++ 中最常發生的錯誤,並且同樣重要,尤其是對於新程式設計師而言。這種型別的連結器錯誤會影響程式的執行。
這些錯誤主要發生在程式編譯成功並且處於連結階段試圖將其他目標檔案與主目標連結時。在某些情況下,程式會給出一些輸出,並且會發生此錯誤。
因此,追蹤和糾正此類錯誤有時會很複雜。
當我們使用了對某個類、函式或變數的任何引用時,就會發生未定義的引用錯誤。連結器無法在所有連結的目標檔案和庫中找到它的定義,從而產生錯誤 Undefined Reference to a Class::Function()。
這些錯誤可能有多種原因,但我們將在這裡討論其中的一些。
由於 C++ 中沒有函式定義,解決對 Class::Function() 的未定義引用
這可能是導致此錯誤的最直接原因,因為你提供了函式的原型但忘記給出其定義。
當你為該函式建立引用時,連結器將無法找到其定義,從而生成錯誤 Undefined Reference to a Class::Function()。
這在下面的示例中得到了證明:
#include <iostream>
class Square {
public:
double length; // Length of a box
double width; // Breadth of a box
double height; // Height of a box
double getArea(void);
};
int main() {
Square sq1;
sq1.getArea();
return 0;
}
輸出:
(.text+0x15): undefined reference to Square::getArea()
collect2.exe: error: ld returned 1 exit status
由於 C++ 中沒有連結的物件檔案,解決對 Class::Function() 的未定義引用
當使用不同的檔案來定義一個類時,我們需要將該檔案包含在主函式檔案中,以便在連結程式時與主物件檔案連結。
在下面的示例中,我們在另一個檔案中單獨定義了 Square 類。在主檔案中,我們引用了它的物件,所以它會給出一個未定義的引用錯誤,因為檔案沒有連結。
例子:
#include <iostream>
using namespace std;
int main() {
Square sq1;
cout << sq1.getArea();
return 0;
}
示例(Square.cpp):
class Square {
public:
double length; // Length of a box
double width; // Breadth of a box
double height; // Height of a box
double getArea(void) { return length * width; }
void setLength(double l) { length = l; }
};
解決這個問題的方法是將 Square.cpp 檔案連結到以下程式碼中的主檔案。
#include <iostream>
#include "square.cpp"
using namespace std;
int main() {
Square sq1;
cout << sq1.getArea();
return 0;
}
由於未在 C++ 中編譯相關檔案,解決對 Class::Function() 的未定義引用
當程式的所有依賴項都沒有成功編譯時,也會出現這種型別的錯誤。為了使連結器成功生成可執行檔案,有必要在啟動連結階段之前編譯所有依賴項。
這是不可避免的,因此連結器可以輕鬆找到所有相關的目標檔案(即 .o 檔案)。如果任何依賴物件檔案丟失,連結器將生成未定義引用錯誤。
g++ 編譯器,Bash 命令 g++ -c abc.cpp 將在不呼叫連結器的情況下生成相應的目標檔案 abc.o。除了上面討論的情況之外,未定義的參考錯誤可能還有許多其他情況。程式設計師必須正確定義所有識別符號(例如,函式、變數和物件)以避免此類問題。