2012-09-07 79 views
4

编辑:有关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 
} 

Derived.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 

Derived.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 
+3

请张贴实际的代码“私人无效派生::快速排序()'是无效的C++是不是Java此外,后期**最小。 **代码。构造函数和析构函数的问题通常不需要derived.cpp中的所有东西,我必须多次滚动才能看到Derived :: Derived(int)没有被定义。 –

+0

Terribly – Jeff

+0

请包括Base.cpp,因为您在源列表中包含两次Base.h;一次为Base.h,另一次为base.cpp。我们可以看到吗?如果Base ::〜Base()被正确定义(最好是,因为它是在头文件中声明的)。 – WhozCraig

回答

7

您已经在Base声明虚析构函数,但你永远无法定义它。它需要在Derived(以及Base中定义,因为它不是纯虚函数),因为它将被调用一次main退出。你应该有:

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

Base::~Base() {} 

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

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

这就是你的错误中至少一个的原因。我不知道这个人是一个红色的鲱鱼或没有,但它似乎是:

/tmp/ccw1aT69.o: In function main': main.cpp:(.text+0x15): undefined reference to Derived::Derived(int)'

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

+1

我同意,但没有看到Base.cpp领主知道什么是实施,什么不是。但Derived ::〜Derived()不必声明+定义;它可以既不(根本不存在)。如果你不这样做,编译器会生成一个默认的版本,并且由于基类是(Base ::〜Base()),它将是虚拟的。但是我们需要base.cpp文件。 – WhozCraig

+0

@CraigNelson:不错,我假设基于此:'未定义的引用Base ::〜Base()' –

+0

对不起...我更新了代码。 – Jeff

0
main.cpp:(.text+0x15): undefined reference to `Derived::Derived(int)' 

此错误消息不说,一个未定义的参考一类作为您的标题问题说。相反,它抱怨一个未定义的参考构造函数它接受一个int参数。从我粗略的看你的代码,你只声明了这个构造函数而没有定义它。添加一个定义到你的.cpp文件,你应该解决这个错误。

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

+0

它不再在源代码库中,但Derived :: Derived(int)在Derived.cpp文件的**底部**处定义。这就是人们顺便说一句,它是为什么你最喜欢发布导致问题的实际代码并且完整性的原因。如果这太复杂了,那么展示相同问题的样本就足够了。 – WhozCraig

+0

@CraigNelson我的不好。和.h文件一样,我在顶层寻找构造函数,而不是底层。 ;-( –

+0

@代码库鲁我在同一艘船上盯着它的前5分钟,所以你并不孤单。 – WhozCraig

3

好的,只是为了清楚起见,因为我不能把格式化的代码放在除了答案之外的任何东西。您不需要在派生类中提供析构函数,只是因为您的基类具有虚拟驱动器或纯方法。以下是我可以在三种不同构造/破坏条件下证明这一点的简单过程。代码后列出输出。我希望这至少可以帮助@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()