什么是实现纯虚函数的必要性

时间:2013-12-04 16:24:07

标签: c++ class virtual-functions

纯虚函数是抽象基类的必备属性。因此,不应该进行任何实现,这非常直观易懂。但最近我才知道纯虚函数仍然可以在以后定义并静态调用(而不是由对象实例调用)。我想不出这个原因。如果将一个虚函数定义为纯函数,那么实现它的原因是什么?

class A{
public:
    ...
    virtual void interface() = 0; //Pure Virtual functions
    ...
}

void A::interface() //Implementation
{
    cout<<"This the implementation for A interface";
}

我很好奇这背后的逻辑。为什么c ++的设计方式如此?

5 个答案:

答案 0 :(得分:2)

有一个“默认”实现可能是有意义的,如果它对它们有用,具体类可以使用。他们仍然需要覆盖它,但可以非虚拟地调用基类版本:

struct B : A {
    void interface() {
        A::interface(); // call the default implementation
        // and maybe do some B-specific things too
    }
};

答案 1 :(得分:1)

  

我无法想出这个原因。如果将一个虚函数定义为纯函数,那么实现它的原因是什么?

纯虚函数的目的是来禁止定义。它是将类标记为不可实现的。

提供定义对于派生类可能很有用:

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

void A::foo()
{
   /* some common logic here */
}

struct B : A
{
   virtual void foo() overrides
   {
      bar();
      A::foo();
   }

   void bar();
};

struct C : A
{
   virtual void foo() overrides
   {
      baz();
      A::foo();
   }

   void baz();
};

答案 2 :(得分:1)

在这种情况下,你显然完全误解了“静态”一词的含义。

是的,纯虚函数仍然可以有实体,即它们仍然可以定义

不,你不能在没有对象实例的情况下调用这样的函数,因为你似乎错误地相信了。具有正文的纯虚函数仍然是非静态成员函数。它仍然需要调用一个对象实例。

当有人说可以“静态”调用此类函数时,这意味着可以直接调用它,而不使用虚拟调度机制。通过虚拟调度的函数调用有时称为“虚拟调用”或“动态调用”,而直接函数调用有时称为“静态调用”。在此上下文中,术语“静态”假定具有完全不同的含义,不以任何方式与静态成员函数相关联。

在C ++语言中,可以通过在调用中指定合格的成员名称来显式执行直接的非虚拟(即“静态”)调用。例如,如果类B派生自您的类A,那么在某个方法B::foo()中,您可以使用以下语法

void B::foo() {
  A::interface(); // <- qualified method name
}

直接调用您提供的A::interface()的实现。对于b类型的对象B,可以执行与

相同类型的调用
B b;
b.A::interface(); // <- qualified method name

在这两种情况下,都会针对特定对象执行调用(第一个示例中为*this,第二个示例中为b

当派生类的析构函数调用基类的析构函数时,几乎同样的事情发生了,这就是为什么你经常会遇到纯虚拟析构函数的情况(即它们被声明为纯虚拟,但有一个体)。 / p>

答案 3 :(得分:1)

纯虚函数只是意味着函数必须被所有派生类覆盖,并不意味着函数不能/不应该有自己的实现。这种具有实现的纯虚函数的两个最明显的情况是:

  • 派生类实现可以调用基类实现
  • 有时你会希望一个基类被抽象化,但是没有方法可以标记为纯virtual,在这种情况下析构函数是最明显的选择,但在这样的析构函数中仍然需要一个实现。

答案 4 :(得分:1)

interface()= 0表示派生类必须提供实现,因此定义会影响派生类,但允许基类具有方法的实现,以便派生类始终可以调用基::接口()。