【问题标题】:C++ - the linker can't find my function, which happens to be an overloaded operator [duplicate]C ++ - 链接器找不到我的函数,这恰好是一个重载的运算符[重复]
【发布时间】:2013-01-17 03:18:08
【问题描述】:

我对 C++ 还是很陌生,所以如果有一个简单的答案,我提前道歉。我正在尝试使用重载运算符。这是该运算符的签名:

const Vector3D operator/(const Vector3D& lhs, const double rhs)

这是我尝试使用它的方法:

OrthonormalBasis::OrthonormalBasis(const Vector3D &a)
{
    Vector3D t;
    w = a / a.length();
    t = getCollinearVector(w);

    //More code goes here
}

当我尝试编译时,g++ 返回以下错误:

/file/path/orthonormalBasis.cpp:8: undefined reference to 
`operator/(Vector3D const&, double)' 
collect2: ld returned 1 exit status

操作符是在 Vector3D.cpp 中定义的,所以我确实有定义。

【问题讨论】:

  • a.length() 不是double,因此操作员的签名不匹配。
  • @vonbrand:如果是这样的话,他会得到编译器错误,而不是链接错误。
  • @Omnifarious:那是因为大多数文本在涵盖工具链方面什么都不做,只关注代码。你可以把我算在这些人中。 7 年后,我仍然在这个过程中挣扎,至少在弄清楚如何将其他库链接到我的程序中时是如此。
  • 老实说,我花了很长时间才了解链接。是的,我从一开始就使用了 IDE(作为课程的一部分)。在迁移到 IDE 之前完成所有基本的手动编译和链接会更有益。

标签: c++ linker operator-overloading constants pass-by-reference


【解决方案1】:

您看到的是链接器错误。链接是在编译后创建可执行文件的阶段。链接器的工作是获取对符号的所有引用并将它们解析为对其定义的引用。

这意味着作为链接器的输入,您必须提供所有符号定义。其中一些将来自库,一些来自.cpp 文件。不幸的是,链接器实际上无法解析 C++。它希望编译器能够做到这一点。编译器会生成一个.o 文件。 .o 文件包含解释符号定义和生成 CPU 可以直接执行的内容的结果。这就是链接器需要的那种定义。

通常将一个重要的程序(即具有多个 .cpp 文件的程序)编译为可执行文件涉及使用编译器创建一堆 .o 文件,然后将它们链接到一个可执行文件中。

在您的情况下,您的符号在Vector3D.cpp 中定义,并在orthonormalBasis.cpp 中使用。我还可以从错误中看出您在某种 Unix 平台上使用g++。编译和链接步骤至少如下所示:

g++ -c Vector3D.cpp
g++ -c orthoNormalBasis.cpp
g++ Vector3D.o orthoNormalBasis.o

我打赌你只是这样做:

g++ orthoNormalBasis.cpp

这是以下的简写:

g++ -c orthoNormalBasis.cpp
g++ orthoNormalBasis.o

如您所见,即使尝试编译 Vector3D.cpp 也完全错过了尝试将生成的 .o 文件链接到可执行文件的尝试。这就是您收到该错误的原因。

【讨论】:

  • 我实际上是在使用 cmake 构建我的项目。当我第一次问我的问题时,我没有意识到这是一个链接问题。感谢您的回答和@BenjaminLindley 的评论,我能够缩小我的问题范围。作为参考,我忘记使用 target_link_libraries 链接外部库。
  • @MrJones:啊。 :-) 因此,实际上并不需要对链接的确切含义进行仔细详细的解释。好吧,我很高兴你解决了你的问题。我怀疑你因为意识到这是一个链接错误而感到困惑,因为你重载了一个人们不常做的操作符。
【解决方案2】:

这主要是您只是声明重载的operator/,而不是定义它,因此链接器无法链接函数的定义。

【讨论】:

  • 重载的operator/ 在 Vector3D.h 中声明,在 Vector3D.cpp 中定义。我错过了什么吗?
  • @MrJones,然后它没有链接到 cpp。
  • @MrJones - 或者,更准确地说,不链接到通过编译Vector3D.cpp 生成的.o 文件。链接器是一个程序,它将所有.o 文件和库汇集在一起​​,并将对符号的引用解析为对其在那些.o 文件和库中的定义的引用。当您看到“未定义的引用”时,通常是链接器错误,无法将对符号的引用解析为对其定义的引用。
猜你喜欢
  • 2021-01-12
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多