2013-04-09 89 views
0

我有一個主要功能,它看起來像這樣:錯誤建築在Xcode

#include <vector> 
#include "mins_ndim.h" 
#include "ObjectiveFunction.h" 

int main (int argc, char * const argv[]) { 

    ObjectiveFunction objective; 
    Frprmn<ObjectiveFunction> frprmn(objective); 
    std::vector<double> p(2); 
    p[0]=7; p[1]=3; 
    frprmn.eat(); 
} 

但是這給我的錯誤:

Undefined symbols: 
    "Frprmn<ObjectiveFunction>::eat()", referenced from: 
     _main in main.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

eat()在Frprmn的結構定義列在mins_ndim.h並在mins_ndim.cpp中定義。如果我在mins_ndim.h中定義它,那麼我不會得到這個錯誤。我認爲這是與鏈接有關的事情,但我不知道如何讓xcode將其排序?!

+0

你的main文件看不到'mins_ndim.cpp',所以如果你在那裏定義'eat()',你會得到一個未定義的符號。 – lcs 2013-04-09 17:16:28

+0

那麼如何使用我在.cpp文件中定義的函數呢?該函數在頭文件中列出,所以我應該可以訪問它。 – tiswas 2013-04-09 17:17:27

回答

1

類模板的成員函數的定義在編譯器使用時必須對其可見。當編譯器遇到frprmn.eat();時,它沒有看到eat(它只看到mins_ndim.h中的聲明)的實現,所以不能生成適當的代碼。

請記住,模板本質上是一段代碼,編譯器必須實例化一個代碼,並將模板類型替換爲適當的模板參數。編譯器需要能夠看到eat的實現能夠以ObjectiveFunction作爲模板參數生成它。

出於這個原因,在頭文件中實現函數模板或類模板的成員函數是很常見的做法。

另一種方法是,如果要保持類模板的定義及其實現是分開的,則應在頭文件的底部處包含實現文件。這顛倒了包容的典型方法。爲了使這一點更清楚,通常使用.tpp擴展名來命名實現文件(模板爲t)。這使得更明顯哪些文件包含哪些文件。

+0

因此,如果我使用的是類模板,那麼就沒有辦法將實現和聲明保存在單獨的文件中(正如我傾向於爲非模板類​​所做的那樣)? – tiswas 2013-04-09 17:23:26

+0

@tiswas除了我在最後一段中描述的小動作,沒有。模板實現必須包含在任何想要使用它們的文件中。只是宣言不會。 – 2013-04-09 17:24:51