2013-11-24 47 views
0

我正在試圖製作一個簡單的程序,我使用模板n繼承。 我正在使用Linux gcc。然而,在eclipse cdt中,如果我只是給自己的makefile,我會得到關於vtable未定義參考的錯誤。另一方面,如果我檢查構建中的選項,即自動生成makefile,錯誤消失。有人能指出什麼可能是錯的嗎?導致vtable錯誤的Makefile設置

這裏是我的班,頭和Makefile

AbstractVehicleFactory.h:

class AbstractVehicleFactory { 
public: 
    AbstractVehicleFactory() {} 
    virtual ~AbstractVehicleFactory() {} 
    IVehicle* getVehicle(); 

    virtual IVehicle* createVehicle() = 0; 
private: 
    IVehicle* mVehicle; 
}; 

AbstractVehicleFactory.cpp

IVehicle* AbstractVehicleFactory::getVehicle() { 
    if(!mVehicle) { 
     mVehicle = createVehicle(); 
    } 
    return mVehicle; 
} 

StandardVehicle.h:

#include "AbstractVehicleFactory.h" 
template<typename T> 
class StandardVehicle: public AbstractVehicleFactory { 
public: 
    StandardVehicle(); 
    virtual ~StandardVehicle(); 
protected : 
    IVehicle* createVehicle(); 
private: 
    T* mVehicle; 
}; 

StandardVehicle.cpp:

template<typename T> 
StandardVehicle<T>::StandardVehicle() { 
    mVehicle = 0; 
} 

template<typename T> 
StandardVehicle<T>::~StandardVehicle() { 
} 

template<typename T> 
IVehicle* StandardVehicle<T>::createVehicle() { 
    return new T(); 
} 

Makefile: 

# compiler 
CXX = g++ 

CXXFLAGS = -O2 -g -Wall -fmessage-length=0 

SOURCES= $(wildcard *.cpp) 

OBJECTS= $(SOURCES:.cpp=.o) 

TARGET= Vehicle.exe 

$(TARGET): $(OBJECTS) 
     $(CXX) -o $(TARGET) $(OBJECTS) $(LIBS) $(LDFLAGS) 

all: $(SOURCES) $(TARGET) 



clean: 
    rm -f $(OBJECTS) $(TARGET) 

Error: 

g++ -o Vehicle.exe AbstractVehicleFactory.o Bus.o FactoryPattern.o IVehicle.o StandardVehicle.o 
AbstractVehicleFactory.o:(.rodata._ZTV22AbstractVehicleFactory[vtable for AbstractVehicleFactory]+0x10): undefined reference to `AbstractVehicleFactory::createVehicle()' 
collect2: ld returned 1 exit status 
make: *** [Vehicle.exe] Error 1 

有人能指出什麼可能是錯的嗎?

編輯:即使在檢查makefile自動生成後,我在StandardVehicle構造函數中出現錯誤爲未定義的引用。 StandardVehicle.o也不顯示任何組件。它沒有正確地建設?

+0

您能否在您的問題中理清哪些代碼屬於哪些編譯單元/頭文件? –

+0

它只是一個包含所有這些文件的文件夾。除了這些IVehicle和公共汽車班。它們分別是界面和最終產品,工廠應根據定義的模板類返回最終產品。像這樣AbstractVehicleFactory * a = new StandardVehicle (); IVehicle * v = a-> createVehicle(); –

+0

我一直在問你指出哪個代碼放在哪個具體文件中,就在你的示例代碼(部分)之前用s.th.像'AbstractVehicleFactory.cpp:'。請編輯你的問題。 –

回答

1

您的代碼表示:

public: 
StandardVehicle() ; 

你不能這樣做,因爲它的模板。你必須有身體有在.H

當你以後在其他CPP文件中像這樣使用模板:

StandardVehicle<int> myvar ; 

編譯器將會使所有的代碼StandardVehicle<int>在那裏當場,所以它不能引用StandardVehicle.cpp中的代碼

+0

哦謝謝,但我不得不將所有函數定義放在模板類的頭文件中。有什麼特別的原因嗎?提前致謝。 –