【问题标题】:"Undefined reference to class::function..." - am I linking incorrectly?“未定义的对 class::function ... 的引用” - 我链接不正确吗?
【发布时间】:2011-03-07 05:20:31
【问题描述】:

我正在学习这个 NeuralNet 课程:

class NeuralNet {
public:
    // Public functions
private:
    vectors vect; // Point-of-access for functions in class vectors
    // Private functions
};

我正在使用这个极其简单的 makefile:

all: nnet.exe
nnet.exe: main.o neuralnet.o vectors.o
    g++ -o nnet.exe main.o vectors.o neuralnet.o
main.o: main.cpp neuralnet.h
    g++ -ggdb -c main.cpp
vectors.o: vectors.cpp vectors.h
    g++ -ggdb -c vectors.cpp
neuralnet.o: neuralnet.cpp neuralnet.h vectors.h
    g++ -ggdb -c neuralnet.cpp
clean:
    rm -f *.o nnet.exe

当 g++ 运行以构建最终的可执行文件时,我收到以下形式的很多错误:

neuralnet.o: /path/to/neuralnet.cpp: line# : undefined reference to vectors::fn_name(args)

例如,我定义了一个函数:

template<typename T> void fill_vec(vector<T>&, int, double);

当我调用这个函数时,我传递一个声明为vector<double> 类型的变量作为第一个参数,链接器报告undefined reference to void vectors::fill_vec<double>(std::vector<double, std::allocator<double> >&, int, double)

NeuralNet 的实现中对class vectors 函数的所有调用都是从vect 调用的。但是,neuralnet.cppneuralnet.h 都包含 "vectors.h" 的包含,所以我假设我在某种程度上链接不正确。

有没有人看到任何明显的东西?

【问题讨论】:

  • neuralnet.h 中是否包含vectors.h?
  • 是的,neuralnet 标头还包含vectors.h。编辑问题以立即反映。
  • 这听起来很愚蠢 - fn_name() (cAsE sEnSiTiVe) 正在正确使用,对吗?在此错误之后,您没有收到“候选人是...”消息或任何内容吗?顺便说一句,这不是一个链接问题。 g++ -c 参数取消链接,直到您的最后一步。
  • @RageD,g++ 提到的文件名是 .o 文件,错误信息是“未定义引用”——这绝对是链接问题。
  • @RageD - 不,没有关于候选函数的任何消息。此外,问题是当使用 g++ 从目标文件构建最终可执行文件时发生错误,也就是应该发生链接的时候。

标签: c++ header linker include makefile


【解决方案1】:

除非你在 vectors.h定义 fn_name() in-line,只包括来自 neuralnet.cpp 的标头和 neuralnet.h 是不够的。确保您实际上可以将手指指向该函数体。您可能打算将它放在 vectors.cpp 中。

成为模板会改变一切。您应该在头文件中定义模板方法,而不是在 .cpp 文件中。尽管您可能在源文件中定义了fill_vec<T>,但编译器实际上并没有为T 的任何值实例化它,因为在该翻译单元中,它不需要任何实例化。您可以为您需要的每个 T 值手动实例化它,但是在您声明它的同一位置的标头中定义函数更容易。这样,编译器在需要的每个地方都有可用的定义。您将获得多个实例化(每个使用它的翻译单元一个),但链接器知道如何整合这些实例。

另见Undefined reference error for template method

【讨论】:

  • 错误信息中出现的fn_name()的变体都是在vectors.cpp中定义的,当然也包括vectors.h——当你说把我的手指指向函数体?
  • 我的意思是你应该确保你能真正找到链接器所说的缺失的变体。函数的零参数版本真的定义了吗?它是在哪一行定义的?我假设链接器说的是真话,并且函数没有真正定义。如果你认为它定义的,证明它。如果你不能用手指指着它说:“这就是它被定义的地方”,那么它就没有被定义。还要确保您没有任何可能导致编译器跳过该函数的 ifdef 指令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 2023-03-16
  • 1970-01-01
  • 2017-03-07
  • 2013-03-20
相关资源
最近更新 更多