【问题标题】:Under what circumstances is it advantageous to give an implementation of a pure virtual function?在什么情况下给出一个纯虚函数的实现是有利的?
【发布时间】:2010-11-01 22:17:57
【问题描述】:

在 C++ 中,给出纯虚函数的实现是合法的:

class C
{
public:
  virtual int f() = 0;
};

int C::f() 
{
  return 0;
}

你为什么要这样做?

相关问题:C++ faq lite 包含一个示例:

class Funct {
public:
  virtual int doit(int x) = 0;
  virtual ~Funct() = 0;
};

inline Funct::~Funct() { }  // defined even though it's pure virtual; it's faster this way; trust me

我不明白为什么析构函数被声明为纯虚拟然后实现;我不明白为什么这应该更快的评论。

【问题讨论】:

    标签: c++ performance pure-virtual


    【解决方案1】:

    必须始终实现已声明的析构函数,因为实现会将它们作为派生对象销毁的一部分调用。

    如果它们提供有用的通用功能但总是需要专门化,则可以实现其他纯虚函数。在这种情况下,派生类实现通常会显式调用基础实现:

    void Derived::f()
    {
        Base::f();
    
        // Other Derived specific functionality
    }
    

    通常,如果您需要将类抽象化(即防止创建非派生实例),则将析构函数设为虚拟,但该类没有其他自然纯虚拟的函数。我认为“相信我,它更快”是指这样一个事实,因为作为派生对象清理的一部分调用的析构函数不需要使用 vtable 查找机制,与典型的虚函数调用不同,可以利用内联实现.

    【讨论】:

      【解决方案2】:

      如果你有派生类可以利用的通用功能。 但他们也需要做其他工作。

      所以派生类实现虚函数,调用底层基版本:

      class X: public C
      {
          public:
              virtual int f()
              {
                  return C::f() + 1; // I am +1 over my parent.
              }
      };
      

      【讨论】:

        【解决方案3】:

        刚刚发现 Herb Sutter 在他的Guru of the Week #31 中回答了这个问题的第一部分。

        【讨论】:

          【解决方案4】:

          生日,

          关于为在基类中声明的成员函数提供默认实现,我目前能想到的唯一原因是您希望提供该行为的默认实现,作为专业人士的可能实现选择基类。

          派生类的作者可以选择使用基类作者提供的默认实现,而不是添加自己的专门实现。

          通常情况下,人们反对使用单独的函数来提供接口和行为的默认实现,但他们仍然希望将默认实现和关联接口分开。

          啊,刚刚看到@Martin York 的帖子,其中提供了一个示例。

          实际上,Scott Meyers 在他的“Effective C++”一书中讨论了这一点。这是第一版的第 36 条。

          HTH

          干杯,

          【讨论】:

            【解决方案5】:

            因为它被认为是不正确的写法:

            class Funct {
            public:
              virtual int doit(int x) = 0;
              virtual ~Funct() = 0 {};
            };
            

            如果你从这个类派生,析构函数仍然会被调用。将所有方法声明为纯虚拟方法只是为了清楚起见。你不妨这样写:

            class Funct {
            public:
              virtual int doit(int x) = 0;
              virtual ~Funct() {};
            };
            

            该类仍然是抽象的,因为至少有一个方法是纯虚拟的。析构函数也是内联的。

            【讨论】:

              【解决方案6】:

              关于虚拟析构函数的速度,这是因为析构函数是在 cpp 文件中定义的,而不是在头文件中。它与大小有关,而不是与速度有关。在“大规模 C++ 软件设计”中有详细说明。不幸的是,我不记得所有的细节,但我认为内联虚函数在 vtable 中被定义了多次。

              这里有一个讨论: Are inline virtual functions really a non-sense?

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-09-29
                • 1970-01-01
                • 2017-01-16
                • 2011-01-06
                • 1970-01-01
                • 2016-03-07
                • 2012-03-21
                相关资源
                最近更新 更多