我有一个听老鼠事件的课程。但是,我不想强迫用户实现任何特定的,但我想明确表示他们必须继承它。
有办法做到这一点吗?
由于
答案 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() {}
默认情况下,所有继承类都不是抽象的,即使它们不需要实现任何方法。