5

我想过使用受保护的构造函数,但它不能完全解决目的,因为从它继承的类将能够实例化基类。

至于私有构造函数,派生类也不会被实例化。

因此,任何合适的技术都会受到赞赏。

4

4 回答 4

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
   }
};
于 2013-07-03T18:18:03.273 回答
1

抽象类的定义是至少具有一个纯虚函数(virtual function-signature = 0;没有它们就无法创建抽象类。

于 2013-07-03T18:18:02.157 回答
1

可以在 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; 
于 2013-07-03T18:28:55.283 回答
0

我在我的书中读到抽象类是一个专门用作基类的类。一个抽象类至少包含一个纯虚函数。通过在类声明中的虚成员函数的声明中使用纯说明符 (= 0) 来声明纯虚函数。

于 2014-12-17T06:39:13.180 回答