非成员函数引用未定义 - C++

6

我在头文件中有以下内容。

namespace silc{
   class pattern_token_map
   {
      /* Contents */
   };

   pattern_token_map* load_from_file(const char*);
}

在CPP文件中(已包含适当的头文件)。
pattern_token_map* load_from_file(const char* filename)
{
   // Implementation goes here
}

在另一个CPP文件中。这里已经包含了所有必需的头文件。
void some_method()
{
    const char* filename = "sample.xml";
    pattern_token_map* map = load_from_file( filename ); // Linker complains about this.
}

我遇到了一个连接器错误,它说找不到对load_from_file的引用。我无法确定出错原因。
如果有帮助就太好了。
编译器:G++ 操作系统:Ubuntu 9.10
编辑:
以下是使用的连接器命令。
g++ -L/home/nkn/silc-project/third_party/UnitTest++ -o tests.out  src/phonetic_kit/pattern_token_map.o  tests/pattern_token_map_tests.o  tests/main.o -lUnitTest++

这个错误来自于 pattern_token_map_tests.o,相关函数在 pattern_token_map.o 中。因此我猜想链接顺序并没有导致问题。(为了简化命令,我已经删除了一些文件)


1
无法从您发布的内容中判断 - 请添加您正在使用的编译器/链接器命令。 - anon
谢谢Neil。我已经添加了链接器命令,这是我正在使用的。它是我所拥有的简化版本。 - Navaneeth K N
1
如果你执行命令"nm pattern_token_map.o | grep load_from_file",你会看到什么? - Richard Pennington
我已经编辑了代码,将该方法放在名为silc的命名空间中。@Andreas:不,我没有使用模板。 - Navaneeth K N
6
load_from_file 的实现是在 namespace silc 块内定义的吗? - Peter Kovacs
显示剩余5条评论
2个回答

9

当你实施时,必须确保你实现了正确的函数:

namespace silc {
pattern_token_map* load_from_file(const char* filename) {
   // Implementation goes here
}
}

如果你做了这个操作:
using namespace silc; // to get pattern_token_map
pattern_token_map* load_from_file(const char* filename) {
   // Implementation goes here
}

那么你将定义一个新函数,而不是silc::load_from_file。

一般指导原则是避免在函数范围之外使用指令(“using namespace ...;”):

using namespace silc; // outside function scope: avoid

silc::pattern_token_map*                      // qualify return type
random_function(silc::pattern_token_map* p) { // and parameters
  using namespace silc; // inside function scope: fine
  pattern_token_map* p2 = 0; // don't have to qualify inside the function
                             // if you want to use the using directive
  silc::pattern_token_map* p3 = 0; // but you can always do this
  return 0;
}

谢谢。通过说“避免在函数外使用指令(“using namespace ...;”)”,您的意思是避免将其写在cpp文件的顶部。相反,应该将其写在每个函数内部。这是您的意思吗? - Navaneeth K N
1
是的,如果你想在函数中使用它,那也可以。但实际上很少需要这样做,因为你可以使用我第一段代码中的形式来在cpp文件中实现你的函数。 - Roger Pate
1
我之前没有想过将using指令限制在函数体内。+1 - Peter Kovacs
虽然大多数人认为这是良好的编码实践,但请注意,遵循它可能会非常烦人。 - Andreas Bonini

0
在链接阶段,您是否将第一个cpp文件编译生成的目标文件链接进来了?当一个目标文件引用了未被链接的符号时,就会出现这样的链接器错误。
编辑:我仍然相信这是问题所在。在第一个文件中,是否有一个预处理器符号重新定义了load_from_file?

是的,我正在链接所有的目标文件。添加了链接器命令。请看一下。 - Navaneeth K N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接