2016-10-03 63 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解决方案简单的问题使我内心温暖和模糊。谢谢! –

相关问题