2012-01-04 73 views
6

每當我編的東西,來#include一個用戶定義的類,我得到這些編譯錯誤總是看起來像:main.cpp: undefined reference to Complex::Complex(double, double)文件包含錯誤(C++):未定義的引用______

我已經減少了問題的一組三個非常空的文件:main.cpp,例如Complex.h和Complex.cpp。我仍然收到未定義的參考錯誤。我在Windows上的Code :: Blocks中開發,但在Ubuntu中使用g ++獲得了同樣的結果。爲什麼會發生?我已經嘗試過在Code :: Blocks中的main.cpp之前構建Complex.cpp,並且我嘗試了g++ main.cpp Complex.cpp,就像我試過g++ main.cpp一樣。每次都有相同的錯誤。

/*======== main.cpp ========*/ 
#include "Complex.h" 

int main() 
{ 
    Complex A(1.0, 1.0); 
    return 0; 
} 

/*======== Complex.h ========*/ 
#ifndef _COMPLEX_H 
#define _COMPLEX_H 

class Complex 
{ 
    public: 
    double x, y; 
    Complex(double real, double imag); 
}; 

#endif 

/*======== Complex.cpp ========*/ 
#include "Complex.h" 

Complex::Complex(double real, double imag) 
{ 
    x = real; 
    y = imag; 
} 

ed:現在我得到了不同的錯誤,所以我必須做一些完全錯誤的事情。使用與上面相同的代碼,我得到:

main.cpp: in function 'int main()': 
main.cpp:5:5: error: 'Complex' was not declared in this scope 
main.cpp:5:13: error: expected ';' before 'A' 

這是離奇的。當我有一個.cpp文件中的類時,所有東西都工作得更早,但這是「不好的做法」,所以我將我的類定義移動到.h文件中,並將實現保存在.cpp文件中,現在什麼都不起作用。

+1

另外一定要在編譯行中加上「-I」。如果你的.h文件在同一個目錄下,甚至可能是「-I」。 – paulsm4 2012-01-05 00:00:53

+3

它適合我。我只複製了你的'main.cpp','Complex.h'和'Complex.cpp',並運行'g ++ main.cpp Complex.cpp'。它創建'a.out'就好了。 – ruakh 2012-01-05 00:01:43

+1

也適用於我。 @ paulsm4:不應該''在默認包含路徑中? (請注意,他正在執行'#include「...」',而不是'#include <...>') – 2012-01-05 00:03:23

回答

6

這不是一個編譯錯誤,它是一個鏈接錯誤。您需要確保將所有對象鏈接在一起。你可以用幾種方法做到這一點:

g++ main.cpp Complex.cpp 

應該工作正常(並在這裏,當我試着用你的例子)。你也可以做到這一點的步驟:

g++ -c main.cpp 
g++ -c Complex.cpp 
g++ main.o Complex.o 
+0

在這個問題中,它已經說過「我已經嘗試過'g ++ main.cpp Complex.cpp」 – 2012-01-05 00:12:17

+0

@AaronMcDaid,但他顯然沒有,因爲那樣會起作用。我想他也可以簡化他的例子,但是這也不會幫助他得到正確的答案。 – 2012-01-05 00:12:56

+0

我同意。我已經提出了你的答案,因爲它似乎顯然是正確的:-)我想我們正在等待確切的錯誤消息的細節。 – 2012-01-05 00:16:18

1

雖然我們都留在了黑暗中,這是否是實際的代碼(很可能不是因爲它適用於其他幾個人),讓代碼本身一點的評論... (這不會對鏈接器錯誤產生任何影響)

  1. 以下劃線開頭,後跟大寫字母的名稱,例如_COMPLEX_H保留用於實現C++編譯器和C++標準庫。 請勿使用
  2. 成員變量最好是private。很少有任何需要讓實際的數據成員public(有時候做非功能成員public是合理的,例如用戶可以預訂回調的事件類,但是它們通常表現爲功能,儘管它們在技術上是對象)。
  3. 初始化最好在成員初始值設定項列表中完成。也就是說,構造函數會是這個樣子:

    複雜::複合物(雙實數,雙圖像): X(真實), Y(IMAG) {}

最後,冒險幾個猜測什麼是錯誤的實際代碼導致鏈接問題:

  1. 構造函數定義爲inline。顯然,除非定義在使用構造函數的地方可見,否則這將不起作用。
  2. Complex聲明以某種方式將它變成了一個未命名的名稱空間,因此定義恰好定義了與main.cpp所看到的類不同的類。