C ++从函数指针复制符号

时间:2013-10-02 00:04:03

标签: c++ duplicate-symbol

我有3个源文件。主文件有一个函数,它使用if语句来定义指针:

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具有flatdispexpdisp的相应定义:

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的函数。这一直有效,直到我将我的功能分解为不同的文件。是什么导致了这个错误?

1 个答案:

答案 0 :(得分:3)

我会假设你想说:

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

链接器抱怨你已经在多个地方定义了符号(a.k.a.变量)“kernel1”。

问题是你在头文件main.h中定义了一个变量“kernel1”。此头文件包含在多个.cpp文件中。因此,您已在多个编译单元中有效地定义了“kernel1”。

解决方案很简单。将“kernel1”的定义移至main.cpp

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

更新已添加到地址评论:

有人指出,符号“kernel1”也在使用另一个文件。 在这种情况下,

  1. “kernel1”的定义仍然需要在main.cpp中发生 如上所述。

  2. 在main.h头文件中添加kernel1的“extern”声明:

    extern arma::vec (*kernel1)(arma::vec d, arma::vec m);
    
  3. 这可以解决您的问题。