|
在CU逛,別人問到這樣的一個問題,大致如下:
#include <iostream>
#include <string>
using namespace std;
class base
  {
public:
 virtual void print() {cout<<"base::print()"<<endl;}
//virtual ~base(){}//增加虛析構函數,將導致輸出不一致。
};
class derived :public base
  {
public:
 virtual void print() {cout<<"devrived::print()"<<endl;}
};
int main(int argc, char *argv[])
  {
base* p1=&derived();
p1->print();

derived d;
base* p2=&d;
p2->print();

return 0;
}
加入虛擬析構函數后,輸出為: base::print() devrived::print() 不加入虛擬析構函數,輸出則為: devrived::print() devrived::print()我的解釋如下: 實際上,第一個賦值指向的是一個臨時對象,加入與沒有加入虛擬析構函數的區別在于:加入之后,在derived類中會合成一個析構函數以便調用base的虛擬析構函數,如果沒有加入的話那么就不會合成這個析構函數,所有的資源在main函數結束之后才回收.
因此,對于代碼: base* p1=&derived(); 沒有加入虛擬析構函數的時候因為derived()函數生成的臨時對象沒有被銷毀,因此對它的調用是對derived的調用;當加入虛擬析構函數之后,derived()函數生成的臨時對象在以上的賦值完成之后就會調用析構函數進行析構,這個時候再次對p1調用print函數時,因為臨時對象已經析構,那么這個調用就是對base的調用了.
我做了一個實驗的代碼,加了一些東西,大家看看~~
|