sud*_*03r 27 c++ virtual-functions
#include <iostream>
using namespace std;
class Duck {
public:
virtual void quack() = 0;
};
class BigDuck : public Duck {
public:
// void quack(); (uncommenting will make it compile)
};
void BigDuck::quack(){ cout << "BigDuckDuck::Quack\n"; }
int main() {
BigDuck b;
Duck *d = &b;
d->quack();
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不能编译.但是,当我在子类中声明虚函数时,它编译得很好.
如果编译器已经具有子类将覆盖的函数的签名,那么为什么需要重新声明?
任何见解?
the*_*row 22
需要重新申报,因为:
Ben*_*ett 11
如果你改变:
virtual void quack() = 0;
Run Code Online (Sandbox Code Playgroud)
至
virtual void quack();
Run Code Online (Sandbox Code Playgroud)
它将编译而不在HugeDuck中实现quack().
= 0; 在函数声明的最后,本质上是说所有BigDuck都会嘎嘎叫,但它必须由每个派生的duck实现.通过删除= 0; 除非你在HugeDuck中实现嘎嘎,否则BigDuck嘎嘎会被调用.
编辑:澄清= 0; 是说派生类将具有该函数的定义.在你的例子中,它期望HugeDuck定义quack(),但是你已经注释掉了它没有.
作为旁注,既然所有的鸭子都可以嘎嘎叫,那么我们看不到你原来的Duck类应该实现quack()呢?
因为C++将'声明'与'多态"分开:任何函数都需要声明编译器,无论它是否为虚拟.
你的例子还不够,它有"抽象类"问题:BigDuck无法实例化,因为它的界面中没有实现quack.
概括问题,我们可以声明基本函数不是纯虚拟的:
class Duck { public: virtual void quack(){} };
class BigDuck : public Duck {};
void BigDuck::quack(){ cout << "QUACK!"; }//overrides, but doesn't declare
Run Code Online (Sandbox Code Playgroud)
在这里,编译器会抱怨它有一个BigDuck::quack未声明的符号.这与抽象类或任何东西无关.
(注:GCC说:
error: no 'void BigDuck::q()' member function declared in class 'BigDuck'
)