2013-01-31 51 views
13

我有一個基類沒有純虛函數的C++抽象類?

class ShapeF 
{ 
public: 
    ShapeF(); 
    virtual ~ShapeF(); 

    inline void SetPosition(const Vector2& inPosition) { mPosition.Set(inPosition); } 

protected: 
    Vector2 mPosition; 
} 
一些ommitied代碼

很明顯,但你明白了吧。 我用這個作爲模板,並用一些有趣的(中省略)枚舉的方式來確定我使用的是什麼樣的形狀

class RotatedRectangleF : public ShapeF 
{ 
public: 
    RotatedRectangleF(); 
    virtual ~RotatedRectangleF(); 
protected: 
    float mWidth; 
    float mHeight; 
    float mRotation; 
} 

ShapeF執行其與定位工作,它定義了一個枚舉類型是。它有訪問器和增變器,但沒有方法。

我可以使ShapeF成爲抽象類,以確保沒有人嘗試實例化ShapeF類型的對象嗎?

通常情況下,這是可行的範圍內ShapeF

//ShapeF.h 
virtual void Collides(const ShapeF& inShape) = 0; 

不過,我目前正在處理在一個單獨的類的碰撞具有純虛函數。 我可以移動一切,但我想知道是否有辦法讓一個類抽象..沒有純虛函數。

+0

您試圖通過標記(枚舉)和鑄造來重新實現動態分配......這將在未來很快變成一種痛苦。我會重新考慮設計。 –

+0

@DavidRodríguez-dribeas我認爲這是最簡單的方法,static_casting的一切。如果我想重新設計,我將完全移除ShapeF(),並且將它全部變成多態,並且讓每個形狀都是它自己的人。除非你有不同的建議? – MintyAnt

回答

39

你可以聲明,和實施,一個純虛析構函數:

class ShapeF 
{ 
public: 
    virtual ~ShapeF() = 0; 
    ... 
}; 

ShapeF::~ShapeF() {} 

這是一個從你已經有一個微小的一步,將防止ShapeF被直接實例化。派生類不需要改變。

+3

快速提問 - 爲什麼'〜ShapeF'在聲明爲「純虛擬」時需要實現? –

+0

謝謝,這個作品完美。任何想法,爲什麼這有效?我想,純粹的虛擬不能被定義。 – MintyAnt

+4

它必須被定義,或者派生類不能銷燬它們的基類。任何純虛函數都可以定義,它允許派生類委託給它們。 –

18

嘗試使用受保護的構造函數

+0

+1,析構函數應該是'protected'和non-virtual。如果'ShapeF'是'new'-ed並且從來沒有'delete'-d(但這本身就是一個bug),那麼在這種情況下,這並不能解決問題。 –

+0

@DavidRodríguez-dribeas爲什麼應該保護析構函數?如果它受到保護,則無法刪除該對象。 –

+0

@JamesKanze:我想*應該*是一個強有力的詞。我有這樣的感覺,析構函數是'virtual'的唯一理由是遵循* always *的建議,使得析構函數是虛擬的,如果這個類型是派生的。使受保護的析構函數解決了相同的底層問題,併爲不實例化問題提供了一個解決方案(至少在堆棧和堆中,除非你對內存泄漏感到滿意:)無論如何,我的感覺是整體應該重新設計設計(就像我在問題的評論中提到的那樣) –