【问题标题】:Adding a body to a pure virtual/abstract function in C++?将主体添加到 C++ 中的纯虚拟/抽象函数?
【发布时间】:2013-12-08 05:41:30
【问题描述】:

纯虚函数不应该有主体,但我刚刚注意到编译器接受了以下代码:

class foo
{
    virtual void dummy() = 0
    {
        cout << "hello";
    }
};

那么,为什么允许纯虚函数有一个实体呢?还有,即使函数有body,类还是不能实例化,这是为什么呢?

【问题讨论】:

  • 我知道删除 =0 将允许我创建对象。但我想这不是我问的问题。我想知道为什么我们不能创建抽象类的对象?
  • @DeveshAgrawal =0 是对编译器的声明,即在您覆盖该方法之前,您不应该实例化该类,这与该方法是否实际实现无关。
  • @DeveshAgrawal 我编辑了您的问题以使其更清楚,我是否正确理解了您的问题?
  • 我知道这已经有几年的历史了,但是当搜索这个主题时,你最终会出现在这里......根据这个(草稿!)open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4849.pdf on 11.7.3, 2:[注意:函数声明不能​​同时提供纯说明符和定义。—尾注] [示例:struct C {virtual void f() = 0 { };// 错误};— 结束示例]。我这边没有解释,你可能想知道

标签: c++ virtual abstract


【解决方案1】:

纯虚函数可以有一个主体,但您将它们声明为纯虚函数的事实恰恰是说派生实现是必需的

您可以从派生方法执行纯虚方法(使用显式BaseClass::method()),但您仍然必须提供实现。

不能用没有被重写的纯虚方法实例化一个类是纯虚声明的要点。换句话说,声明一个纯虚拟方法的想法是确保程序员不会忘记提供它的实现。

【讨论】:

  • 另请注意,您必须为纯虚拟析构函数提供一个主体。
  • @AndreKostur:我认为(从逻辑的角度来看)纯虚拟析构函数没有多大意义。此外,必须提供纯虚方法基类实现并不常见(任何可以放在基类实现中的东西也可以更合理地放在常规实用方法中)。 Common Lisp 中提供了对方法组合的更精细的语义描述......对于 C++ 来说,将纯虚拟扩展到 IMO 是个坏主意。
【解决方案2】:

一般来说,抽象类用于定义接口和/或部分实现,并旨在被具体类继承。这是在类 designer 和该类的 users 之间强制执行contract 的一种方式,无论他们是什么。

如果你不需要这个契约并且想要实例化,那么不要强制它是抽象类,即删除= 0

如果您关心的是为什么纯虚函数首先要有主体,那么一个很好的例子就是 Scott Meyers 的 Effective C++ 一书中的这句话:

实现这个纯虚函数的派生类可以调用 这个实现在他们代码的某个地方。如果部分代码 两个不同的派生类是相似的,那么移动是有意义的 它在层次结构中向上,即使函数应该是纯虚拟的。

另一个例子是纯虚析构函数(顺便说一下也是一个函数):

...

virtual ~foo() = 0;

...

foo::~foo() {} // required!

当您需要为其提供实现,但同时又希望将其设为纯虚拟以使 foo 类抽象时。所以,其实语言本身的核心就是依赖这个特性的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2011-03-21
    • 2019-04-20
    • 2013-01-15
    • 2019-12-08
    • 1970-01-01
    • 2011-07-25
    相关资源
    最近更新 更多