2010-11-09 69 views
24

我不明白爲什麼這不起作用。我會把所有的三個文件放在一起,可能有人會告訴我爲什麼它會拋出這個錯誤。我正在使用g ++來編譯程序。C++未定義的參考定義的功能

計劃:

#include <iostream> 
#include "h8.h" 

using namespace std; 

int main() 
{ 
    char sentence[MAX_SENTENCE_LENGTH]; 
    char writeTo[] = "output.txt"; 
    int distanceTo,likePosition, length, numWords; 
    cout << "ENTER A SENTENCE! "; 
    cin.getline(sentence, 299); 
    length = strlen(sentence); 
    numWords = wordCount(sentence, length); 
    for(int x = 0; x < 3; ++x) 
    { 
    likePosition = likePos(numWords); 
    distanceTo = lengthTo(sentence, likePosition, length); 
    insertLike(sentence, distanceTo, length, writeTo); 
    } 
    return 0; 
} 

功能文件:

void insertLike(const char sentence[], const int lengthTo, const int length, char writeTo[]) 
{ 
    char part1[MAX_SENTENCE_LENGTH], part2[MAX_SENTENCE_LENGTH]; 
    char like[] = " like "; 
    for(int y = 0; y < lengthTo; ++y) 
    part1[y] = sentence[y]; 
    for(int z = lengthTo+1; z < length - lengthTo; ++z) 
    part2[z] = sentence[z]; 
    strcat(part1, like); 
    strcat(part1, part2); 
    writeToFile(sentence, writeTo); 
    return; 
} 

頭文件

void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]); 

錯誤到底是:

undefined reference to 'insertLike(char const*, int, int, char const*)' 
collect2: ld returned 1 exit status 

回答

18

聲明和insertLike定義是不同的

在你的頭文件:

void insertLike(const char sentence[], const int lengthTo, const int length,爲const char的writeTo []);

在你的'函數文件'中:

void insertLike(const char sentence[], const int lengthTo, const int length,炭的writeTo []);

C++允許函數重載,在這裏可以有一個具有相同名稱的多個功能/方法,只要它們具有不同的參數。參數類型是函數簽名的一部分。

在這種情況下,insertLike這需要const char*作爲它的第四個參數和insertLike這需要char *作爲它的第四個參數是不同的功能

+0

我完全/ headfloor馬上。 – Mashew 2010-11-09 04:17:01

+21

有時它只需要一個額外的眼球,男人。 :)我記得當我學習C時,我會用半天的時間把頭撞在鍵盤上,然後我的岳父回到家,指着我的肩膀,「你錯過了一個分號那裏。」 >。> – Mud 2010-11-09 04:19:04

+6

那麼,從來沒有一個岳父岳母。可能是我爲什麼花了超過半天的時間在挫敗中敲擊了我的頭在鍵盤上:-) – 2014-06-04 18:47:14

14

你需要編譯和鏈接的所有源文件一起:

g++ main.c function_file.c 
+2

我意識到這是近5歲,但我是一個總的C++新手,這對我工作。謝謝。 – 2015-05-01 03:04:20

+1

同樣在這裏,試圖在Debian機器上編譯一些VS代碼,只是發現這個,謝謝你的答案!你甚至可以做'G ++ * .c',按照http://stackoverflow.com/questions/3202136/using-g-to-compile-multiple-cpp-and-h-files#comment3301067_3202161 – 2015-09-24 22:53:17

18

儘管之前的海報涵蓋了您的特定錯誤,但如果您不告訴編譯器使用C鏈接,當嘗試使用g ++編譯C代碼時,可能會收到'Undefined reference'鏈接器錯誤。

例如,你應該在你的C頭文件做到這一點:

extern "C" { 

... 

void myfunc(int param); 

... 

} 

,使 'MYFUNC' 在C++程序可用。

如果您還也想用這個從C,包裹在#ifdef __cplusplus預處理條件的extern "C" {},像

#ifdef __cplusplus 
extern "C" { 
#endif 

這樣,extern塊將只是「跳過」使用的是C編譯器時。

+0

謝謝,這使我停止了瘋狂。在關鍵時刻! – Robert 2014-04-04 18:20:32

+0

鏈接器真的應該檢查這個案例,並告訴你有一個定義的函數的非麻煩版本! – jtbr 2017-04-17 21:36:32

+0

謝謝,這爲我解決了它。我還需要補充: 的#ifdef __cplusplus 的extern 「C」{ #ENDIF 和 的#ifdef __cplusplus } #ENDIF 在我的C頭文件的頂部和底部,因爲它們引用通過C++和C代碼。 – karora 2017-09-07 11:17:34

2

如果您使用CMake,也可能發生這種情況。如果您創建了一個新類並且想要實例化它,那麼在構造函數調用時,您將收到此錯誤 - 即使標題和cpp文件正確 - 即使您未相應地修改CMakeLists.txt也會收到此錯誤。

隨着CMake的,每次你創建一個新的類時,使用它的頭前,cpp文件和任何其他編譯文件(如Qt的ui文件)必須被添加到CMakeLists.txt,然後重新運行,其中CMakeLists.txt存儲cmake .

例如,在此CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8.11) 

project(yourProject) 

file(GLOB ImageFeatureDetector_SRC *.h *.cpp) 

### Add your new files here ### 
add_executable(yourProject YourNewClass.h YourNewClass.cpp otherNewFile.ui}) 

target_link_libraries(imagefeaturedetector ${SomeLibs}) 

如果您使用的是命令file(GLOB yourProject_SRC *.h *.cpp),那麼你只需要重新運行cmake .無需修改CMakeLists.txt

+0

'make rebuild_cache'是另一種強制重新配置的方法。另外,這就是爲什麼你不能用文件名'GLOB'構造你的CMakeLists。畢竟,他們被稱爲CMake **列表是有原因的。 – ulidtko 2017-01-04 17:44:32