【问题标题】:Does it make any sense to define "pure" virtual functions in the base class itself?在基类本身中定义“纯”虚函数是否有意义?
【发布时间】:2011-12-25 05:24:20
【问题描述】:

在基类中定义通用虚函数的好处是我们不必在派生类中重新定义它们。

即使我们在基类本身中定义了虚函数,我们仍然必须在派生类中定义它们。

#include <iostream>
using namespace std;

class speciesFamily
{
    public:
        virtual void numberOfLegs () = 0;
};

void speciesFamily :: numberOfLegs ()
{
    cout << "\nFour";
}

class catFamily : public speciesFamily
{
    public:
        void numberOfLegs ()
        {
            speciesFamily :: numberOfLegs ();
        }
};

这肯定看起来很花哨,但是在任何情况下在基类本身中定义纯虚函数是有益的吗?

【问题讨论】:

  • 请注意,那里的答案有一些共同点。除了析构函数的特殊情况,基类中的实现只会被派生类显式调用。它也可以有一个不同的名称,所以“好处”就是它与预期调用它的覆盖具有相同的名称,从而避免像_default_base 这样的疣。

标签: c++ pure-virtual


【解决方案1】:

只有纯虚函数的基类是像 Java 这样的语言所称的接口。它只是描述了可用的功能,仅此而已。

【讨论】:

  • 除了在C++中,纯虚函数可以有实现。因此问题是,你什么时候想给他们实现?
  • @MikeSeymour 如果一个虚函数有一个实现,它就不再是纯函数了。基(接口)类有虚函数,而派生类有普通虚函数。
  • 如果声明为纯虚函数(即后跟=0),则它是纯函数。这使得类抽象(防止实例化,除了作为基类),但没有说明函数是否具有实现。正如我所说,纯虚函数可以有实现。
【解决方案2】:

纯虚函数没有合理的实现可以在基类中是有益的。在这种情况下,纯虚函数在派生类中实现。

【讨论】:

  • 除了问题是,什么时候在 base 类中实现它们会有好处。
  • @Mike Seymour:例如,在基类中实现一些默认行为以避免代码重复是有益的
【解决方案3】:

在基类本身中定义纯虚函数是否有好处?

是的 - 如果所讨论的函数是纯虚析构函数,它必须也由基类定义。

【讨论】:

  • 谢谢,还有其他情况吗?
【解决方案4】:

两件事:

首先,有一个经常被引用的边界线场景:假设您想要一个抽象基类,但您没有个虚函数可以放入其中。这意味着您没有使纯虚拟化的功能。现在有一种解决方法:由于您总是需要一个虚拟析构函数,因此您可以将其设为纯析构函数。但是你也需要一个实现,所以这是你的候选人:

struct EmptyAbstract
{
  virtual ~EmptyAbstract() = 0; // force class to be abstract
};
EmptyAbstract::~EmptyAbstract() { } // but still make d'tor callable

这可以帮助您最小化抽象类的实现大小。不知何故,这是一个微优化,但如果它符合语义,那么有这个选项很好。

第二点是您始终可以从派生类调用基类函数,因此您可能只想拥有一个“通用”功能集,尽管不想要任何抽象实例。再次,纯虚拟定义函数:

struct Base
{
  virtual void foo() = 0;
};

struct Derived : Base
{
  virtual void foo()
  {
    Base::foo();  // call common features
    // do other stuff
  }
};

void Base::foo() { /* common features here */ }

【讨论】:

  • 我不明白这个suppose you want an abstract base class, but you have no virtual functions to put into it.抽象类的意义意味着它的对象不能被创建。美好的。现在,如果我们连虚函数都没有放进去,那么创建那个抽象基类有什么意义呢?在这种情况下是否有意义的任何示例情况?
  • @AnishaKaul:我从来没有说过这是有道理的! C++ 是一种丰富而复杂的语言,它允许你做各种在纸上逻辑上可能的事情。并非所有这些都是实际有用的(如受保护的继承或函数尝试块)。谁知道呢,也许你只是想要一个没有特性的空白类型擦除基类?一些喜欢动态转换的人可能会使用一个空的公共基类......实际上,这些婴儿甚至很难编写这一事实可能表明这不是一个预期的功能经常被使用。
  • @AngelO'Sphere:这并不抽象;它只是使实例化变得更加困难(但并非不可能)。它也不会使其具有多态性,这(或多或少)是您想要一个不声明虚函数的抽象类的唯一原因。
  • @AngelO'Sphere:没什么好混淆的。在 C++ 中,如果一个类具有纯虚函数或未覆盖的纯虚基函数(句号),则该类是“抽象的”。
  • @AngelO'Sphere:这个问题是关于 C++ 的,其中“抽象类”和“多态类”的含义分别由语言标准定义为“具有至少一个纯虚函数”和“具有至少一个虚函数的类”。这些词的其他含义在其他上下文中可能有用,但在用于描述其他 C++ 概念时只会引起混淆。
猜你喜欢
  • 2012-10-06
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2023-03-31
  • 2013-07-03
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多