C++中是否可以实现没有纯虚函数的抽象类?

5

我考虑使用受保护的构造函数,但这不能完全解决问题,因为继承它的类仍然可以实例化基类。

至于私有构造函数,派生类也将无法实例化。

因此,任何适当的技术都将不胜感激。


8
如果至少没有一个纯虚函数,那么它就不是一个抽象类。 - Captain Obvlious
4
你到底想做什么? - Beta
我试图模仿纯虚函数在类中的效果,而不在类中使用虚拟虚拟函数! - Sankalp
你为什么要这样做?你想强制派生类实现该函数,但同时在基类中提供实现吗?你应该编辑你的问题并澄清你想做什么,为什么要这样做,如果可能的话,提供代码示例说明你想如何实现它。 - Captain Obvlious
4个回答

3

不清楚您真正需要的是什么。因此,让我尝试澄清一些要点:

纯虚函数可以有定义

如果您关心的是要为基类中的所有虚函数提供定义,则可以提供纯虚函数的定义,这些定义将可用于静态分派。

protected 管理访问你的base子对象,而非每个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
   }
};

@Sankalp:这并没有说出你想要做什么,只是你达到目的的方法。你想要做什么需要伪造抽象类吗? - David Rodríguez - dribeas

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; 

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

@g-makulik - 这是C++语言中的定义。 - Pete Becker
@PeteBecker,但是抽象类只是一个概念(一个无法实例化的类)。看一下静态多态性的概念,你会发现可以创建抽象类而不使用纯虚函数。 - πάντα ῥεῖ
@PeteBecker 我做了一些研究,发现您关于“抽象类”这个术语与 C++ 语言的官方定义似乎是正确的(总是被解释为“至少具有一个纯虚函数定义”的类)。但我仍然认为,如果一个 CRTP 基模板类没有为某个接口方法提供默认实现,它可以/应该被视为一个抽象类 - πάντα ῥεῖ

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接