【发布时间】:2010-11-28 01:53:43
【问题描述】:
以下两个声明有什么区别?
virtual void calculateBase() = 0;
virtual void calculateBase();
我读到第一个 (=0) 是“纯抽象函数”,但第二个是什么?
【问题讨论】:
标签: c++ function virtual abstract
以下两个声明有什么区别?
virtual void calculateBase() = 0;
virtual void calculateBase();
我读到第一个 (=0) 是“纯抽象函数”,但第二个是什么?
【问题讨论】:
标签: c++ function virtual abstract
第一个是“纯虚拟”——它会使类抽象,试图实例化它会导致编译器错误。它旨在用作派生类通过实现纯虚函数来实现必要行为的基类。您不必在基类中实现该函数,但您可以。
这是一种常用于两种设计模式的模式:
第二个声明只是一个普通的虚成员函数声明。如果未能在基类中实现成员函数,则会出现编译器错误。它仍然是虚拟的,这意味着覆盖派生类中的行为可能很有用。
【讨论】:
第一个称为纯虚函数。通常纯虚函数不会有任何实现,您不能创建包含纯虚函数的类的实例。
第二个是虚函数(即“普通”虚函数)。一个类提供了这个函数的实现,但是它的派生类可以通过为这个方法提供它自己的实现来覆盖这个实现。
【讨论】:
第一个不必在基类中实现,但强制它在继承类中实现。
你必须在基类中实现第二个,它可以在继承类中实现。
【讨论】:
基本上,在继承时,强制覆盖第一个,允许覆盖第二个。
来自 Java,不是吗?
【讨论】:
我认为你在混淆术语......
virtual void x() = 0;
是一个纯虚函数,或抽象函数。它是一个没有实现的虚函数。你谈论一个纯抽象类,它是一个接口的 c++ 等价物,关于一个只有抽象函数的类。
virtual void x();
是一个虚函数,意味着它可以在派生类中重新定义,但它不是抽象的,所以你必须为它提供一个实现。
【讨论】:
虚空calculateBase() = 0;
第一个函数是纯虚函数,不能在类中实现,它充当纯抽象类或接口类。具体的实现应该在子类中完成或覆盖。它充当其派生类的接口类。
虚空calculateBase();
这个函数是虚函数,实现(默认)可以在基类中完成。但是,派生类必须重写它自己的实现。
【讨论】:
在 Java 中
virtual void calculateBase() = 0;
会
abstract void calculateBase();
和
virtual void calculateBase();
会
void calculateBase();
说清楚,
void calculateBase();
在 C++ 中,与“相同”
final void calculateBase();
在 Java 中。也就是说,final 在 C++ 中是“默认值”。然而,这条规则有一个例外。当使用虚方法子类化一个类并在不使用 virtual 关键字的情况下重新实现它时,子类中的方法将是最终的。
【讨论】:
第二个函数必须在声明它的类中有一个实现(缺少'= 0'),并且可以被子类覆盖。
第一个函数在声明它的类中可能有也可能没有实现,并且必须由子类实现
【讨论】: