2012-09-07 80 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()