我想过使用受保护的构造函数,但它无法完全解决目的,因为继承它的类能够实例化基类。
对于私有构造函数,派生类也不会被实例化。
所以,任何合适的技术都会受到赞赏。
答案 0 :(得分:3)
目前还不清楚你真正要求的是什么。所以让我试着澄清一些观点:
纯虚函数可以有定义
如果您担心要为基础中的所有虚拟函数提供定义,则可以提供纯虚函数的定义,它们可用于静态调度。
受保护授予您对基础子对象的访问权限,而不是对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
}
};
答案 1 :(得分:1)
抽象类的定义是至少有一个纯虚函数的定义(virtual function-signature = 0;
没有它们就不能创建抽象类。
答案 2 :(得分:1)
在C ++中没有纯虚函数可以实现抽象类吗?
如果您从 Static Polymorphism 选择观点,就可以!
抽象基类只是缺少派生类中接口方法的默认方法实现。
此外,您可以对这些CRTP基类模板使用受保护的构造函数,以要求继承实例化。
<强>更新强>
我找到了一个很好的幻灯片,全面地解释了static vs dynamic polymorphism。每种技术都有它的优点和缺点以及某些使用领域,另外你可以混合使用这两种技术(当然是明智的)。
详细说明一点,我将举例:
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;
答案 3 :(得分:0)
我在书中看到了它 抽象类是一个专门用作基类的类。抽象类包含至少一个纯虚函数。您可以在类声明中的虚拟成员函数声明中使用纯说明符(= 0)声明纯虚函数。