【问题标题】:Linking with g++ undefined reference与 g++ 未定义参考链接
【发布时间】:2014-05-06 10:02:52
【问题描述】:

我写了以下代码:

//--a.cpp--//
#include <stdio.h>

class A
{
public:
    void bar();
    virtual void foo()=0;
};

class B: public A
{
public:
    void foo()
    {
        A::bar();
    }
}
int main()
{
    B *b= new B();
    b->foo();
    return 0;
}

//--b.cpp--//
#include <stdio.h>
class A
{
public:
    void bar()
    {
        printf("class A");
    }
}

现在我正在编译和链接这些模块,如下所示:

g++ -c a.cpp
g++ -c b.cpp
g++ -o bin a.o b.o

但是undefined reference error 是由链接器引发的。我不明白,为什么?

【问题讨论】:

  • 您在 b.cpp 中重新定义了类 A,而不是实现。
  • @πάνταῥεῖ 你的意思是我必须将 A 的防御淹没在标题中吗?
  • 是的,把A的声明放到头文件中,像往常一样把A::bar()的实现放到a.cpp中。

标签: c++ class linker linker-errors


【解决方案1】:

您还没有在a.cpp 中定义A::bar()。在B::foo() 中调用了该方法,但它没有实现。所以链接器无法链接它。

b.cpp 中,您创建了另一个类名A,但它与第一​​个无关。它不会在这里产生任何问题,但是如果您将任何一个文件包含到另一个文件中或将两个文件包含在第三个文件中(尽管包含 .cpp 并不常见),您将得到 Redefinition Error )。一个翻译单元中必须只有一个名称定义。

通常的做法是在头文件(.hXX)中声明类,并在源文件(.cXX)中实现方法。如果您希望方法为inlined,那么您可以在标头中定义或将方法显式声明为内联。见Translation UnitODR

【讨论】:

  • 这是由于违反 ODR 而导致的未定义行为 - 您不允许有两个具有相同名称的不同类定义。 (这就是为什么建议使用匿名namespace 来定义单元本地的类定义)
猜你喜欢
  • 2019-07-24
  • 1970-01-01
  • 2016-01-29
  • 2017-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多