【问题标题】:Undefined reference to a derived class对派生类的未定义引用
【发布时间】:2026-01-22 09:20:04
【问题描述】:

编辑:与c++ undefined reference to `vtable相关

我正在尝试做一个关于继承的项目,但我收到了这个错误:

/tmp/ccw1aT69.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)'
/tmp/ccw1aT69.o: In function `Derived::~Derived()':
main.cpp:(.text._ZN20DerivedD2Ev[_ZN20DerivedD5Ev]+0x13): undefined reference to `vtable for Derived'
main.cpp:(.text._ZN20DerivedD2Ev[_ZN20DerivedD5Ev]+0x1f): undefined reference to `Base::~Base()'
collect2: ld returned 1 exit status

这是我的代码:

main.cpp:

#include <iostream>
#include "Base.h"
#include "Derived.h"

int main() {
    Derived intList(25);
}

base.h:

#ifndef BASE_H
#define BASE_H

class Base {
    public:
            ...
            Base (const Base& otherList);
            virtual ~Base();
    protected:
            int *list;
            int length;
            int maxSize;
};

#endif

Base.cpp:

#include "Base.h"
#include <iostream>

using namespace std;

...definitions of my members...

Base::Base (int size) {
//stuff
}
Base::~Base() {
    delete [] list;
}
Base::Base (const Base& otherList) {
//stuff
}

派生的.h:

#ifndef DERIVED_H
#define DERIVED_H
#include "Base.h"

class Derived: public Base {
    public:
             ...
            Derived (int size = 100);
            ~Derived(); //THIS LINE ADDED AFTER FIRST ANSWER
};

#endif

派生的.cpp:

#include "Derived.h"
#include <iostream>

using namespace std;

Derived::Derived (int size)
        :Base(size){
}

是什么导致了这个错误?看起来我不能调用构造函数,但对我来说看起来不错。

编辑:我尝试了第一个解决方案。现在出错:

/tmp/ccA4XA0B.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)'
main.cpp:(.text+0x21): undefined reference to `Derived::~Derived()'
collect2: ld returned 1 exit status

【问题讨论】:

  • 请发布真实代码“private void Derived::quickSort()` 无效。C++ 不是 Java。另外,请发布 minimal 代码。构造函数和问题析构函数通常不需要derived.cpp 中的所有内容,我不得不滚动几次才能看到Derived::Derived(int) 没有定义。
  • 非常抱歉所有代码...我不确定需要什么。
  • 请包含 Base.cpp,因为您在源列表中包含了两次 Base.h; Base.h 一次,base.cpp 一次。只有这样我们才能看到 Base::~Base() 是否被正确定义(最好是,因为它是在标题中声明的。
  • 请注意,使用包含析构函数定义的新编辑,您现在已经破坏了The Rule of Three,并且很快就会遇到段错误(希望如此!)。
  • 这是我有点困惑的地方——我已经定义了所有三个,但是由于它们是虚拟的,所以我的继承类必须再次定义它们,对吧?

标签: c++ constructor undefined-reference


【解决方案1】:

您在Base 中声明了一个虚拟析构函数,但您从未定义它。它需要在Derived 中定义(以及在Base 中,因为它不是纯虚函数),因为它会在main 退出时被调用。你应该有:

class Base {
public:
    // ...
    virtual ~Base();
};

Base::~Base() {}

class Derived : public Base {
public:
    // ...
    ~Derived();
};

Derived::~Derived() { /* whatever */ }

这至少是您的一个错误的原因。我不知道这个是不是红鲱鱼,但它似乎是:

/tmp/ccw1aT69.o:在函数main': main.cpp:(.text+0x15): undefined reference toDerived::Derived(int)'

你定义了Derived::Derived(int),所以很难想象这是一个真正的错误。定义你的析构函数,看看它是否消失。

【讨论】:

  • 我同意,但没有看到 Base.cpp 主知道什么实现了,什么没有实现。但是 Derived::~Derived() 不必声明+定义;两者都不是(根本不存在)。如果您不这样做,编译器将生成一个默认版本,并且它将是虚拟的,因为基类是 (Base::~Base())。但我们需要 base.cpp 文件。
  • @CraigNelson:是的,我假设基于此:undefined reference to Base::~Base()'
  • @Jeff:我在你的代码中没有看到任何地方提到orderedArrayListType。使用我对问题 #1 的解决方案,我认为您可以推断出问题 #2 的原因
  • @Jeff:我对你的帖子发表了评论。你发布了你的析构函数实现,它有问题。如果没有遇到双重delete,则无法复制您的类的实例
  • 我想我让它变得更简单了。
【解决方案2】:

好的,只是为了清楚起见,因为除了答案之外,我无法将格式化的代码放入任何内容中。您不需要仅仅因为您的基类具有虚拟 dtor 或纯方法就在派生类中提供析构函数。以下是我可以在三种不同的构造/破坏条件下证明这一点的最简单的方法。输出列在代码之后。我希望这至少有助于@Jeff。我在 VS2005/2008/2010 和一个古老的 gcc 4.1.2 下测试了这个,所以最好是对的。

#include <iostream>

class Base {
public:
    Base()
        { std::cout << "Base()" << std::endl; };

    virtual void call_me() = 0;

    virtual ~Base()
        { std::cout << "~Base()" << std::endl << std::endl; };
};

class Derived : public Base {
public:
    Derived(int i=1)
        { std::cout << "Derived(" << i << ")" << std::endl; }

    // Base::call_me requirements.
    void call_me() 
        { std::cout << "call_me()" << std::endl; }
};

int main(int argc, char* argv[])
{
    // use derived class pointer type
    Derived* pDerived = new Derived();
    pDerived->call_me();
    delete pDerived;

    // use base class pointer type
    Base* pBase = new Derived(2);
    pBase->call_me();
    delete pBase;

    // scope based
    {
        Derived obj(3);
        obj.call_me();
    }
    return 0;
}

这个的输出是:

Base()
Derived(1)
call_me()
~Base()

Base()
Derived(2)
call_me()
~Base()

Base()
Derived(3)
call_me()
~Base()

【讨论】:

    【解决方案3】:
    main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)'
    

    此错误消息并未像您的标题问题所说的那样说明对 class 的未定义引用。相反,它抱怨对带有 int 参数的 constructor 的未定义引用。从我粗略地看一下你的代码,你只声明了这个构造函数,没有定义它。将定义添加到您的 .cpp 文件中,您应该可以解决此错误。

    此外,将构造函数声明放在所有成员函数声明之前是常见的做法。起初我错过了这些声明,因为它们不是我所期望的。我强烈建议您这样做是为了避免将来在此处提问时产生误解。

    【讨论】:

    • 它不再在源代码库中,但 Derived::Derived(int) 定义在 Derived.cpp 文件的 底部。顺便说一句,人们,这就是为什么最好发布导致问题的实际代码并完整地这样做的主要原因。如果这太复杂了,那么表现出相同问题的样本就足够了。
    • @CraigNelson 我的错。与 .h 文件一样,我在顶部而不是底部寻找构造函数。 ;-(
    • @Code-Curu 盯着它看的前 5 分钟我在同一条船上,所以你并不孤单。
    • 我可以发布所有代码......不过它会大得离谱......我的 .h 文件应该以不同的方式完成吗?
    • 引起关注的不是 .h,而是 .cpp 文件。人们通常不希望在底部找到构造函数。没什么不好的,就是有点奇怪。导致不止一个人认为构造函数未定义只是因为他们没想到会在实现文件的底部找到它。番茄/番茄。
    最近更新 更多