我想过使用受保护的构造函数,但它不能完全解决目的,因为从它继承的类将能够实例化基类。
至于私有构造函数,派生类也不会被实例化。
因此,任何合适的技术都会受到赞赏。
我想过使用受保护的构造函数,但它不能完全解决目的,因为从它继承的类将能够实例化基类。
至于私有构造函数,派生类也不会被实例化。
因此,任何合适的技术都会受到赞赏。
目前尚不清楚您真正要求的是什么。所以让我试着澄清一些观点:
纯虚函数可以有定义
如果您担心要为基础中的所有虚函数提供定义,您可以提供纯虚函数的定义,它们将可用于静态调度。
受保护的授予访问您的基础子对象,而不是每个实例base
有一个常见的误解是protected
允许特定的派生类型访问base
. 那不是真的。关键字protected
授予base
对派生类型中子对象的访问权限。
class base {
protected: base() {}
};
class derived : public base {
derived() : base() { // fine our subobject
base b; // error, `b` is not your subobject
}
};
抽象类的定义是至少具有一个纯虚函数(virtual function-signature = 0;
没有它们就无法创建抽象类。
可以在 C++ 中实现没有纯虚函数的抽象类吗?
如果你选择静态多态的观点,你就可以做到!
抽象基类只是缺少派生类中接口方法的默认方法实现。
此外,您可以为这些 CRTP 基类模板使用受保护的构造函数,以要求继承进行实例化。
更新:
我找到了一个不错的幻灯片,它全面地解释了静态与动态多态性。每种技术都有其优点和缺点以及某些使用领域,此外,您可以混合使用两种技术(当然是明智的)。
为了详细说明,我将给出一个示例:
template<class Derived>
class AbstractBase
{
public:
// Equivalent for a pure virtual function
void foo()
{
// static_cast<> enforces an 'Is a' relation from Derived to AbstractBase
static_cast<Derived*>(this)->fooImpl();
}
// Equivalent for simple virtual function (overidable from Derived)
void bar()
{
static_cast<Derived*>(this)->barImpl();
}
// Default implementation for any call to bar()
void barImpl()
{
}
protected:
AbstractBase() {}
};
// Compilation will fail, since ConcreteClass1 doesn't provide
// a declaration for fooImpl()
class ConcreteClass1
: public AbstractBase<ConcreteClass1>
{
}
// Compiles fine
class ConcreteClass2
: public AbstractBase<ConcreteClass2>
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
以下示例显示了上面介绍的模式在抽象类和继承类(模板参数)之间强制执行“Is a”关系
class ConcreteClass3
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
// Instantiation will fail, because
// * the constructor is protected
// * at least the static cast will fail
AbstractBase<ConcreteClass3> instance;
我在我的书中读到抽象类是一个专门用作基类的类。一个抽象类至少包含一个纯虚函数。通过在类声明中的虚成员函数的声明中使用纯说明符 (= 0) 来声明纯虚函数。