在没有任何纯虚方法的情况下创建类抽象

时间:2011-01-09 18:38:09

标签: c++

我有一个听老鼠事件的课程。但是,我不想强​​迫用户实现任何特定的,但我想明确表示他们必须继承它。

有办法做到这一点吗?

由于

5 个答案:

答案 0 :(得分:55)

您可以声明纯虚拟析构函数,但为其定义。该类将是抽象的,但任何继承类在默认情况下都不是抽象的。

struct Abstract
{
     virtual ~Abstract() = 0;
};

Abstract::~Abstract() {}

struct Valid: public Abstract
{
        // Notice you don't need to actually overide the base
        // classes pure virtual method as it has a default
};


int main()
{
    // Abstract        a;  // This line fails to compile as Abstract is abstract
    Valid           v;  // This compiles fine.
}

答案 1 :(得分:43)

将基础的构造函数指定为protected。这确实意味着您不能直接构造它,而是强制继承。除了良好的文档之外,没有任何东西可以让开发人员从该类继承!

示例:

struct Abstract {
protected:
    Abstract() {}
};

struct Valid: public Abstract {
    // No need to override anything.
};


int main() {
    // Abstract a;  // This line fails constructor is protected
    Valid v;  // This compiles fine.
}

答案 2 :(得分:4)

您可以将基类视为具有您实现的纯虚析构函数。由于析构函数始终由编译器提供,因此派生类将不是纯虚拟的,但无法直接实例化基类。如果你的类有一个虚方法,你应该总是声明一个虚析构函数,这不会产生任何代价。

class Base
{
public:
    virtual ~Base() = 0;
    virtual void SomeVirtualMethod();
};

inline Base::~Base()
{
}

class Derived : public Base
{
};

inline Base* createBase()
{
    // return new Base; // <- This won't compile
    return new Derived; // <- This compile, Derived is not a pure virtual class !
}

答案 3 :(得分:1)

如果用户不必执行任何操作,您为什么要让用户继承?

当需要基类能够将所有“eventhandler”放在std :: set中时。然后没有人可以创建一个类并将其放在这个集合中,而无需继承基类。因为该集将定义为

std::set<MyBaseClass*> mySet;

答案 4 :(得分:1)

根据定义,抽象类是一个至少有一个纯虚函数的类。出于您的目的,您可以将析构函数定义为纯虚拟,并提供实现:

class abstract { 
        virtual ~abstract()=0; 
}; 

abstract::~abstract() {} 

默认情况下,所有继承类都不是抽象的,即使它们不需要实现任何方法。