2016-10-03 39 views
4

考慮以下類:我可以強迫一個類繼承嗎?

//! Counter class base. Must be inherited. 
class base_seeded_counter 
{ 
public: 
    //! Destructor 
    virtual ~base_seeded_counter() { }; 

    //! Get the next value. 
    int get_next(); 

protected: 
    //! Override the counter next value. 
    void set_next(const int next); 

private: 
    int m_next_value; // Next value. 
} 

// ------------------------------------------------------ 

inline int base_seeded_counter::get_next() 
{ 
    return m_next_value++; 
} 

// ------------------------------------------------------ 

inline void base_seeded_counter::set_next(const int next) 
{ 
    m_next_value = next; 
} 

這個類的目的是實現與它必須繼承意圖的基礎計數器對象。它不具有除析構函數以外的任何虛擬方法,更重要的是,不會初始化m_next_value成員。這是派生類的工作。例如:

class file_seeded_counter : public base_seeded_counter 
{ 
public: 
    file_seeded_counter(const std::string &file_name); 

    void reseed(); 

private: 
    std::string m_file_name; 
} 

inline int file_seeded_counter::file_seeded_counter(const std::string &file_name) : 
    m_file_name(file_name) 
{ 
    reseed(); 
} 

inline void file_seeded_counter::reseed() 
{ 
    int seed_from_file; 

    // open file here and get seed value... 

    set_next(seed_from_file); 
} 

這個類,從base_seeded_counter導出從文件中讀取的初始計數器值,並提供通過reseed()方法重新讀取從該文件的種子的能力。例如,可能有其他類提供類似的功能來從數據庫,網絡資源或PRNG開始播種。

我的問題是這樣的:鑑於我沒有純粹的虛擬方法,C++是否提供了一種機制來阻止某人創建base_seeded_counter的實例?

+0

我可以問你**你爲什麼要達到這個目標?如果你創建一個抽象類,爲什麼它會打擾你,如果它會被實例化? – Majster

+0

@majster - 好問題。我的例子中的類在技術上是抽象的,但是因爲它的所有方法都被實現了,所以編譯器把它看作一個具體的類。編譯器沒有看到的是'm_next_value'永遠不會被初始化,當計數器沒有返回預期的結果時可能會導致一些嚴重的問題。我的興趣在於確保其他開發人員不能像這樣做一些傻事:'base_seeded_counter foo;'並讓他們的代碼中斷。 –

+0

不要依賴派生類來初始化'm_next_value'。在基類中將它初始化爲一些理智的東西,比如'0',並讓派生類將它重置爲他們選擇的值。 –

回答

4

鑑於您已經有了一個虛擬析構函數,顯而易見的方法是聲明它是純虛擬的。這是完全合法擁有這也是在基類中定義的純虛析構函數:

class base_seeded_counter { 
public: 
    virtual ~base_seeded_counter() = 0; 
    int get_next(); 
protected: 
    void set_next(const int next); 
private: 
    int m_next_value; 
} 

inline virtual base_seeded_counter::~base_seeded_counter() {} 

定義的析構函數這種方式不改變的事實,這是一個純粹虛擬的,所以這個類不能被實例化。


另外,您目前在代碼中的評論是100%無用的視覺噪聲。對名爲get_next的函數的get next的評論沒有增加任何有用的內容。

+0

另一個出色的解決方案。謝謝!順便說一句,在實際的代碼中,評論並不是這樣的,我應該在示例中完全刪除它們:-) –

+0

我選擇這個作爲答案,因爲它是我選擇實現我的最終解決方案的方式(我的課程還沒有一個構造函數,但它確實有一個虛擬析構函數)。兩種解決方案都是絕對有效的。 –

+0

_ @ Jerry_比我更長,更難以理解解決方案。 –

13

我的問題是這樣的:鑑於我沒有純粹的虛擬方法,C++是否提供了一種機制來阻止某人創建base_seeded_counter的實例?

是的,給它一個protected默認的構造函數(可能爲空)。

+0

Consise解決方案簡單的問題使我內心溫暖和模糊。謝謝! –

相關問題