230

纯虚函数和虚函数有什么区别?

我知道“纯虚函数是一个没有实体的虚函数”,但这意味着什么以及下面的行实际上是做什么的:

virtual void virtualfunctioname() = 0
4

4 回答 4

282

虚函数使其类成为多态基类。派生类可以覆盖虚函数。通过基类指针/引用调用的虚函数将在运行时解析。也就是说,使用对象的动态类型而不是其静态类型

 Derived d;
 Base& rb = d;
 // if Base::f() is virtual and Derived overrides it, Derived::f() will be called
 rb.f();  

纯虚函数是声明以 结尾的虚函数=0

class Base {
  // ...
  virtual void f() = 0;
  // ...

纯虚函数隐式地使它为抽象类定义(不像在 Java 中你有一个关键字来显式声明类抽象)。抽象类不能被实例化。派生类需要覆盖/实现所有继承的纯虚函数。如果不这样做,它们也会变得抽象。

C++ 的一个有趣的“特性”是一个类可以定义一个具有实现的纯虚函数。(这有什么好处是值得商榷的。)


请注意,C++11 为deleteanddefault关键字带来了新用法,看起来类似于纯虚函数的语法:

my_class(my_class const &) = delete;
my_class& operator=(const my_class&) = default;

有关使用and的更多信息,请参阅此问题问题。deletedefault

于 2010-04-16T10:37:48.690 回答
38

对于虚函数,您需要在基类中提供实现。然而,派生类可以用它自己的实现覆盖这个实现。通常,不提供纯虚函数实现。您可以=0在函数声明的末尾将函数设为纯虚函数。此外,包含纯虚函数的类是抽象的,即您不能创建此类的对象。

于 2010-04-16T10:38:31.620 回答
24

纯虚函数通常不会(但可以)在基类中实现,而必须在叶子类中实现。

您可以通过将“= 0”附加到声明中来表示该事实,如下所示:

class AbstractBase
{
    virtual void PureVirtualFunction() = 0;
}

然后你不能声明和实例化一个子类而不实现纯虚函数:

class Derived : public AbstractBase
{
    virtual void PureVirtualFunction() override { }
}

通过添加override关键字,编译器将确保存在具有相同签名的基类虚函数。

于 2010-04-16T10:36:00.303 回答
10

您实际上可以在 C++ 中提供纯虚函数的实现。唯一的区别是所有纯虚函数必须由派生类实现,然后才能实例化类。

于 2010-04-16T10:39:27.390 回答