C++ 对派生类的未定义引用

C++ 对派生类的未定义引用,c++,constructor,undefined-reference,C++,Constructor,Undefined Reference,编辑:与 我正在尝试执行一个有关继承的项目,但遇到以下错误: /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): un

编辑:与

我正在尝试执行一个有关继承的项目,但遇到以下错误:

/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.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
}
派生的.cpp:

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

using namespace std;

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

您已经在
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):对
Derived::Derived(int)”的未定义引用

您定义了
派生::派生(int)
,因此很难想象这是一个真正的错误。定义析构函数,看看它是否消失

main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)'
这个错误消息并没有像标题问题所说的那样指出对类的未定义引用。相反,它抱怨的是对构造函数的未定义引用,该构造函数使用int参数。粗略地看一下您的代码,您只声明了这个构造函数,而没有定义它。将定义添加到.cpp文件中,您应该解决此错误


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

好的,为了清楚起见,因为除了答案之外,我不能在任何内容中添加格式化代码。您不需要仅仅因为基类具有虚拟dtor或纯方法而在派生类中提供析构函数。下面是在三种不同的构造/析构函数条件下演示这一点的最简单的方法。输出列在代码后面。我希望这至少对@Jeff有帮助。我在VS2005/2008/2010和一个古老的GCC4.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;
}

请将实数代码“私有空洞派生::QuasoStReTo”无效。C++是java的最小代码。构造函数和析构函数的问题通常不需要派生的.CPP中的所有东西,我必须滚动几次才能看到<代码>派生::未定义。非常抱歉,所有的代码……我不确定需要什么。请包含Base.cpp,因为您在源代码列表中包含了Base.h两次;一次用于Base.h,另一次用于Base.cpp。只有这样,我们才能看到Base::~Base()的定义是否正确(最好是这样,因为它是在标题中声明的。请注意,使用包含析构函数定义的新编辑,您现在已经中断,并且肯定会遇到segfault(希望如此!)不久的将来。这就是我有点困惑的地方——我已经定义了所有三个,但由于它们都是虚拟的,我继承的类必须重新定义它们,对吗?我同意,但没有看到Base。cpp上帝知道什么是实现的,什么不是。但是派生::~Derived()不必声明+定义;它可以两者都不存在(根本不存在)。如果您不这样做,编译器将生成一个默认版本,并且它将是虚拟的,因为基类是(base::~base())。但我们需要base.cpp文件。@CraigNelson:True,我基于此假设:
对base的未定义引用::~base()“
@Jeff:我看不到您的代码中任何地方提到了
orderedArrayListType
。使用我的问题解决方案#1,我想您可能能够找出问题的原因#2@Jeff:我在您的帖子上留下了评论。您发布了析构函数实现,但它有问题。没有runni,无法复制类的实例我想我把它简化了一点。它不再在源代码库中,而是派生的::派生的(int)是在派生的.cpp文件的底部定义的。顺便说一句,这是为什么人们更喜欢发布导致问题的实际代码并完整地进行发布的主要原因。如果这太复杂了,那么展示相同问题的示例就足够了。@CraigNelson My bad。与.h文件一样,我一直在寻找c施工人员在顶部,而不是底部-(@Code Curu我盯着它看的头5分钟都在同一条船上,所以你不是一个人。我可以发布所有的代码…但是它会大得可笑…我的.h文件应该做得不同吗?不是.h文件让人头晕目眩,而是.cpp文件。人们通常不会期望在底部找到构造函数。没什么错有一点奇怪。导致不止一个人建议构造函数未定义,只是因为他们不希望在实现文件的底部找到它。Tomato/Tomato。
class Base {
public:
    // ...
    virtual ~Base();
};

Base::~Base() {}

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

Derived::~Derived() { /* whatever */ }
main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)'
#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()