2013-10-02 67 views
0

我有一個3個源文件。主要文件有使用if語句來定義一個指針的函數:函數指針的C++重複符號

main(int dispersalfn) { 

if(dispersalfn == 0) { 
    kernel1 = flatdisp; 
    } else if(dispersalfn == 1) { 
    kernel1 = expdisp; 
    } 

[...more stuff...] 

} 

main.h我有kernel1定義:

arma::vec (*kernel1)(arma::vec d, arma::vec m); 

disp.cpp我有flapdispexpdisp定義:

arma::vec flatdisp(arma::vec d, arma::vec m) { 
    return m; 
} 

arma::vec expdisp(arma::vec d, arma::vec m) { 
    return (square(m)/(2*M_PI)) % exp(-m % d); 
} 

disp.h有相應的de爲flatdispexpdisp finitions:

arma::vec flatdisp(arma::vec d, arma::vec m); 
arma::vec expdisp(arma::vec d, arma::vec m); 

最後upfun.cpp有許多調用kernel1功能。 upfun 中的功能由main()調用。

當我編譯,我得到一個錯誤:

duplicate symbol _kernel in upfun.o and main.o for architecture x86_64 

我所有的頭文件源彼此有包括警衛,所以我不認爲這是它。這個想法是,當我打電話給main()時,我包含變量來選擇哪個函數用於kernel1。這工作,直到我把我的功能分解成不同的文件。什麼導致這個錯誤?

+0

似乎是一個鏈接器問題你使用#ifndef HEADER_H #define HEADER_H你應該提供一個工作示例 – Leosar

回答

3

我會認爲你的意思是說:

duplicate symbol _kernel1 in upfun.o and main.o for architecture x86_64 

鏈接器抱怨你已經在不止一個地方定義的符號(又稱可變)「kernel1」。

問題是,您已經在頭文件main.h中定義了一個變量「kernel1」。此頭文件包含在多個.cpp文件中。因此,您已經在多個編譯單元中有效地定義了「kernel1」。

解決方案很簡單。移動的「kernel1」 的定義的main.cpp代替:

arma::vec (*kernel1)(arma::vec d, arma::vec m); 

更新添加到地址評論:

有人指出,「kernel1」正在從另一個文件使用,也象徵。 在這種情況下,

  1. 的「kernel1」的定義仍然需要如上述那樣在 main.cpp中發生。

  2. 添加kernel1的 「外部」 的聲明中main.h頭文件:

    extern arma::vec (*kernel1)(arma::vec d, arma::vec m); 
    

這應該解決您的問題。

+0

當我這樣做,我得到錯誤'upfun.cpp:18:錯誤:'kernel1'沒有聲明在這個範圍內。由於'upfun'中的函數需要'kernel1'(但是它在'main'中定義),它需要在頭文件中。 Per @Leonardo上面,我有'#ifndef HEADER_H #define HEADER_H'包含所有頭文件中的守衛。 –

+0

@Noam Ross:我已經更新了我的回答,以解答您的意見。 – joyjit

+0

這部分解決了這個問題。它消除了這個錯誤,但後來,在加載時,我得到錯誤'Symbol not found:kernel1'。原來,我還必須在'main.cpp'中聲明'kernel1'的默認值。 –