我的基本理解是没有纯虚函数的实现,然而,我被告知可能有纯虚函数的实现。

class A {
public:
    virtual void f() = 0;
};

void A::f() {
    cout<<"Test"<<endl;
}

上面的代码可以吗?

让它成为一个带有实现的纯虚函数的目的是什么?


当前回答

纯虚函数有或没有主体仅仅意味着派生类型必须提供它们自己的实现。

如果派生类想要调用基类实现,基类中的纯虚函数体非常有用。

其他回答

如果您有应该由派生类执行的代码,但不希望它直接执行——并且希望强制重写它。

您的代码是正确的,尽管总的来说这不是一个经常使用的特性,而且通常只在试图定义纯虚析构函数时才会看到——在这种情况下,您必须提供一个实现。有趣的是,一旦从该类派生出来,就不需要重写析构函数了。

因此,纯虚函数的一个合理用法是将纯虚析构函数指定为“非final”关键字。

下面的代码是惊人的正确:

class Base {
public:
  virtual ~Base() = 0;
};

Base::~Base() {}

class Derived : public Base {};

int main() { 
  // Base b; -- compile error
  Derived d; 
}

是的,这是正确的。在您的示例中,派生自A的类继承了接口f()和默认实现。但是你强迫派生类实现方法f()(即使它只是调用A提供的默认实现)。

Scott Meyers在Effective c++ (2nd Edition)第36项中讨论了这一点,区分接口的继承和实现的继承。项目编号可能在最新版本中发生了变化。

'virtual void foo() =0;'语法并不意味着你不能在当前类中实现foo(),你可以。这也并不意味着您必须在派生类中实现它。 在你扇我之前,让我们来看看钻石问题: (注意,是隐式代码)。

class A
{
public: 
    virtual void foo()=0;
    virtual void bar();
}

class B : public virtual A
{
public:
    void foo() { bar(); }
}

class C : public virtual A
{
public:
    void bar();
}

class D : public B, public C
{}

int main(int argc, const char* argv[])
{
    A* obj = new D();
    **obj->foo();**
    return 0;
}

现在,obj->foo()调用将导致B::foo()和C::bar()。

你看到…纯虚方法不必在派生类中实现(foo()在类C中没有实现-编译器将编译) 在c++中有很多漏洞。

希望我能帮上忙:-)

它的优点是它强制派生类型仍然重写方法,但也提供了默认的或添加的实现。

使用带有实现主体的纯虚拟方法的一个重要用例是,当您想拥有一个抽象类,但该类中没有任何合适的方法使其成为纯虚拟时。在这种情况下,您可以将类的析构函数设为纯虚函数,并为此放置所需的实现(甚至是空体)。举个例子:

class Foo
{
   virtual ~Foo() = 0;
   void bar1() {}
   void bar2(int x) {}
   // other methods
};

Foo::~Foo()
{
}

这种技术使得Foo类是抽象的,因此不可能直接实例化该类。与此同时,您还没有添加一个额外的纯虚方法来使Foo类抽象。