在什么情况下提供纯虚函数的实现是有利的?

时间:2009-06-10 19:01:54

标签: c++ performance pure-virtual

在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

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

6 个答案:

答案 0 :(得分:23)

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

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

void Derived::f()
{
    Base::f();

    // Other Derived specific functionality
}

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

答案 1 :(得分:4)

如果您具有派生类可以使用的常用功能。 但他们也需要做其他工作。

因此派生类实现虚函数并调用底层基本版本:

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

答案 2 :(得分:4)

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

答案 3 :(得分:2)

天儿真好,

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

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

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

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

实际上,Scott Meyers在他的“Effective C ++”一书中对此进行了讨论。它是第1版的第36项。

HTH

欢呼声,

答案 4 :(得分:0)

因为它被认为形成了不良形式:

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

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

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

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

答案 5 :(得分:0)

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

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