可能重复:C虚拟/纯虚拟解释
纯虚函数和虚函数有什么区别?
我知道“纯虚函数是一个没有正文的虚函数”,但这意味着什么,以及下面这一行实际完成的内容:
virtual void virtualfunctioname() = 0
虚函数使其类成为多态基类 . 派生类可以覆盖虚函数 . 通过基类指针/引用调用的虚函数将在运行时解析 . 也就是说,使用对象的动态类型而不是其静态类型:
Derived d; Base& rb = d; // if Base::f() is virtual and Derived overrides it, Derived::f() will be called rb.f();
纯虚函数是一个虚函数,其声明以 =0 结尾:
=0
class Base { // ... virtual void f() = 0; // ...
纯虚函数隐式地使它为抽象定义的类(与Java中不同,在Java中你有一个关键字来显式声明类抽象) . 抽象类无法实例化 . 派生类需要覆盖/实现所有继承的纯虚函数 . 如果他们不这样做,他们也会变得抽象 .
一个有趣的'feature'的C是一个类可以定义一个具有实现的纯虚函数 . (What that's good for is debatable . )
请注意,C 11为 delete 和 default 关键字带来了一个新用法,它看起来类似于纯虚函数的语法:
delete
default
my_class(my_class const &) = delete; my_class& operator=(const my_class&) = default;
有关 delete 和 default 的使用的详细信息,请参阅this question和this one .
对于虚函数,您需要在基类中提供实现 . 但是,派生类可以使用自己的实现覆盖此实现 . 通常,对于纯虚函数,不提供实现 . 您可以在函数声明结束时使用 =0 创建一个纯虚函数 . 此外,包含纯虚函数的类是抽象的,即您无法创建此类的对象 .
纯虚函数通常不是(但可以)在基类中实现,必须在叶子类中实现 .
您通过在声明中附加“= 0”来表示这一事实,如下所示:
class AbstractBase { virtual void PureVirtualFunction() = 0; }
然后,如果没有实现纯虚函数,则无法声明和实例化子类:
class Derived : public AbstractBase { virtual void PureVirtualFunction() override { } }
通过添加 override 关键字,编译器将确保存在具有相同签名的基类虚函数 .
override
你实际上可以在C中provide implementations of pure virtual functions . 唯一的区别是所有纯虚函数必须在派生类之前实现,才能实例化 .
4 回答
虚函数使其类成为多态基类 . 派生类可以覆盖虚函数 . 通过基类指针/引用调用的虚函数将在运行时解析 . 也就是说,使用对象的动态类型而不是其静态类型:
纯虚函数是一个虚函数,其声明以
=0
结尾:纯虚函数隐式地使它为抽象定义的类(与Java中不同,在Java中你有一个关键字来显式声明类抽象) . 抽象类无法实例化 . 派生类需要覆盖/实现所有继承的纯虚函数 . 如果他们不这样做,他们也会变得抽象 .
一个有趣的'feature'的C是一个类可以定义一个具有实现的纯虚函数 . (What that's good for is debatable . )
请注意,C 11为
delete
和default
关键字带来了一个新用法,它看起来类似于纯虚函数的语法:有关
delete
和default
的使用的详细信息,请参阅this question和this one .对于虚函数,您需要在基类中提供实现 . 但是,派生类可以使用自己的实现覆盖此实现 . 通常,对于纯虚函数,不提供实现 . 您可以在函数声明结束时使用
=0
创建一个纯虚函数 . 此外,包含纯虚函数的类是抽象的,即您无法创建此类的对象 .纯虚函数通常不是(但可以)在基类中实现,必须在叶子类中实现 .
您通过在声明中附加“= 0”来表示这一事实,如下所示:
然后,如果没有实现纯虚函数,则无法声明和实例化子类:
通过添加
override
关键字,编译器将确保存在具有相同签名的基类虚函数 .你实际上可以在C中provide implementations of pure virtual functions . 唯一的区别是所有纯虚函数必须在派生类之前实现,才能实例化 .