1. 关于虚函数
问:虚函数是否必须有定义?
答:该类(包括该类的派生类)有实例对象时,虚函数必须有定义。
实际应用中:定义基类对象时,基类虚函数必须有定义;定义派生类对象时,继承来的虚函数要么被隐藏,要么必须有定义;但是,无论基类还是派生类中的虚析构函数,必须有定义,因为派生类中析构函数会调用基类的析构函数。
特别的,“pure virtual函数必须在derived classes中重新声明,但它们也可以拥有自己的实现”。定义derived classes实例对象时,pure virtual必须有定义(重新定义,因为派生类只继承了纯虚函数接口)。
1 class Base 2 { 3 public: 4 virtual void mf1()=0; 5 }; 6 void Base::mf1() 7 { 8 cout<<"Base's mf1"<<endl; 9 } 10 class Derived:public Base 11 { 12 public: 13 //using Base::mf1; 14 //纯虚函数必须有定义才能有derived实例对象 15 virtual void mf1() 16 { 17 Base::mf1(); //使用纯虚函数,能够避免derived类“忘记”定义自己版本的对应函数,而误使用了缺省版本 18 } 19 }; 20 21 int main() 22 { 23 Derived d; 24 d.mf1(); 25 26 return 0; 27 }
2. 关于抽象类
问:有时候需要抽象class,但手上没有任何纯虚函数,怎么办:
答:为该类声明一个pure virtual 析构函数。
实际应用中:抽象类不能定义实例对象;定义派生类对象时,必须为基类纯虚析构函数提供一份定义,且定义在类的外部。因为派生类的析构函数会调用基类析构函数;普通纯虚函数可以不提供定义,若定义必须在类外。