2010-06-20 170 views
3

我的基類:從派生模板類調用函數

//Element.h 
class Element 
{ 
public: 
Element(); 
virtual ~Element(){}; // not sure if I need this 

virtual Element& plus(const Element&); 
virtual Element& minus(const Element&); 
}; 

派生模板類:

//Vector.h 
#include "Element.h" 

template <class T> 
class Vector: public Element { 
T x, y, z; 

public: 
//constructors 
Vector(); 
Vector(const T& x, const T& y = 0, const T& z =0); 
Vector(const Vector& u); 
...  
//operations 
Element& plus(const Element&) const; 
Element& minus(const Element&) const; 
... 
}; 
... 

//summation 
template <class T> 
Element& Vector<T>::plus(const Element& v) const 
{ 
const Vector<T>& w = static_cast<const Vector<T>&>(v); 
Vector<T>* ret = new Vector<T>((x + w.x), (y + w.y), (z + w.z)); 
return *ret; 
} 

//difference 
template <class T> 
Element& Vector<T>::minus(const Element& v) const 
{ 
const Vector<T>& w = static_cast<const Vector<T>&>(v); 
Vector<T>* ret = new Vector<T>((x - w.x), (y - w.y), (z - w.z)); 
return *ret; 
} 

我還有另外一個問題,這個代碼(在another post回答),但目前我摔跤的事實,如果我試圖運行這個,我得到

未定義的符號: 「Element :: plus(元素常量&)」,從引用:
虛函數表的Vectorin main.o
「元素::元素()」,從引用:在main.o中
載體::向量()
載體::向量(雙常量&,雙常量&,在main.o中雙常量&)
「元素::減(元常量&)」,從引用:
虛函數表的Vectorin main.o
「所屬類別的元素」,引用來自:
typeinfo for Vectorin main。 Ø
LD:符號(S)沒有發現
collect2:LD返回1退出狀態

這是否是因爲衍生的模板類不是裝在同一個文件的基類,這是導致編譯問題(類似於我必須在頭文件中定義整個Vector類)?

我對C++相當陌生,並且仍然在閱讀vtable是什麼以及它們是如何工作的,但我還不能完全理解這一點。

+0

既然你問過,所有的公共基類應該有一個虛擬的析構函數,這樣它們就可以被正確地刪除。 – GManNickG 2010-06-20 17:30:08

+0

@GMan:請不要在一般情況下說*「所有公共基礎課程」*,它真的讓我的寵物狗狗:) @尼克:看看Sutters [虛擬世界](http://www.gotw .ca/publications/mill18.htm),或至少是其摘要。另外請注意,它奇怪的是你在'plus()'/'minus()'中返回堆分配的實例,爲什麼不在堆棧上創建它們呢? – 2010-06-20 18:55:24

+0

@Georg:爲什麼不呢? :)通過基本指針刪除未定義的行爲,而不使用虛擬構造函數。真正確保這不是問題的唯一方法是不要公開基地。 – GManNickG 2010-06-20 21:07:51

回答

1

我認爲編譯器/鏈接器意味着它告訴你Undefined symbols: "Element::plus(Element const&)"。這些符號(元素的加號和減號)已被聲明,但尚未定義。

+0

如上 - 它是固定的! – 2010-06-20 17:05:29

1

這真的和Vector無關。你申明方法如virtual Element& plus(const Element&)Element::Element()Element.h,但你必須定義他們的某處,大概在Element.cc。如果你已經這麼做了,而且你仍然收到這個錯誤,那幾乎肯定意味着你沒有將Element.o鏈接到你的可執行文件中,所以鏈接器根本不知道在什麼時候放入什麼Vector(或其他任何東西)調用這些方法。

+0

太棒了 - 我不知道我不得不實際定義函數,我想我可以簡單地通過聲明它們。精彩! – 2010-06-20 17:04:26

3

如果我理解的很好,你想要一個抽象的「元素」,並從「元素」派生「矢量」。在這種情況下,你應該刪除你的「Element」構造函數,並且通過在聲明的末尾添加「= 0」來聲明「plus」和「minus」是純虛擬的。雖然你的析構函數很好。

這就是所有的錯誤信息:當你在元素中聲明瞭一個構造函數和一些方法,並且最終調用它們時,鏈接器會查找它們。

我覺得你會希望你的Vector類在矢量上實現「加號」和「減號」,而不是在抽象元素上。這樣,你不需要靜態轉換。你也可以避免一個痛苦的世界,因爲你的返回類型會帶來巨大的風險。

+0

是的,我會玩弄 - 我正在進入繼承的帷幕,我不太確定是否需要靜態投射。我會嘗試不同的方式來使它工作。 – 2010-06-20 17:08:15