1. 程式人生 > >C++物件模型中的虛擬函式分析

C++物件模型中的虛擬函式分析

對於虛擬函式,知道它的含義,也能夠描述出來。參照百度百科,也就是“它提供了‘動態繫結機制”。

可總是感覺有些迷糊,於是敲了一段程式碼出來試驗,一探究竟(程式設計環境是VC6.0)。對比程式碼和結果,一切都不言自明。

現在把程式碼和結果貼上來,作為儲存記錄,同時也歡迎大家提出意見,以臻完善。

#include "stdafx.h"
#include <iostream>

using namespace std;

class Base
{
 public:
 Base()
 {
	cout << "Base class"<< endl;
	print();
	cout << "Base class 建立完畢"<< endl;
 }
 virtual void print(){ cout << "Base print" <<endl;}
 virtual void cmpfl(float a,float b){cout<<(a>b?2:0)<<'\n';}
 virtual ~Base(){
   cout <<"Base虛構了"<< endl;
 }
private:
};

 class Sub:public Base 
{
  public:
  Sub()
  {
	  cout << "Sub class" << endl;
	  print();
	  cout << "Sub class 建立完畢"<< endl;
  }
  virtual void print(){cout << "Sub print" << endl;}
  virtual ~Sub()
  {
    cout <<"Sub虛構了0"<< endl;
  }
  private:
 };
class JSon:public Sub 
{
  public:
  //char *info;
  static int sung;
  JSon()
  {
	  //info="我不知道該說什麼";
	  sung++;
	  cout << "JSon class" << endl;
	  print();
	  cout << "JSon class 建立完畢"<< endl;
  }
  void prints(){cout << "JSon print" << endl;}
  void cmpfl(float a,float b){cout<<(a>b?2:0)<<'\n';}
  virtual ~JSon()
  {
	  cout<<"JSon虛構了"<<endl;
	//delete info;
  }
  private:
 };
int JSon::sung=0;
 

int main(int argc, char* argv[])
{
 Sub c;
 cout<<"---------------\n";
 Base *b=&c;
 cout<<"---------------\n";
 Base *Bk=new Sub();
  cout<<"---------------\n";
 Sub  *Bn=new JSon();
  cout<<"---------------\n";
 JSon *sn=new JSon();
  cout<<"---------------\n"; 
 Sub  *sj=(Sub *)sn;
 cout<<"---------------\n";
 cout<<"基類指向子類物件虛擬函式呼叫---------------\n";
 b->print();
 cout<<"基類用子類宣告虛擬函式呼叫---------------\n";
 Bk->print();
 cout<<"子類用孫類宣告虛擬函式呼叫---------------\n";
 Bn->print();
 Bn->cmpfl(1.31256,1.67346);
 cout<<"孫類物件函式呼叫json\n";
 sn->print();
 sn->cmpfl(1.31252,1.65349);
 //cout <<sn->info<< endl;
 cout<<"----------------------------------------\n";
 cout<<"基類用孫類虛擬函式呼叫,子類未修改也未顯式宣告\n";
 b->cmpfl(1.91252,1.67386);
 cout<<"子類用孫類虛擬函式呼叫,子類未修改也未顯式宣告\n";
 c.cmpfl(1.51252,1.62346);

 cout<<"顯式刪除子類物件指標---------------\n";
 delete sj;
 cout<<"---------------\n";
 cout<<"本程式中JSon被建立的次數是:"<<JSon::sung<<endl;
 cout<<"函式行將結束,虛擬解構函式呼叫情況\n";

 //delete sn;
 //delete Bk;
 //delete b;
 return 0;
 }
執行結果如下:

Base class
Base print
Base class 建立完畢
Sub class
Sub print
Sub class 建立完畢
---------------
---------------
Base class
Base print
Base class 建立完畢
Sub class
Sub print
Sub class 建立完畢
---------------
Base class
Base print
Base class 建立完畢
Sub class
Sub print
Sub class 建立完畢
JSon class
Sub print
JSon class 建立完畢
---------------
Base class
Base print
Base class 建立完畢
Sub class
Sub print
Sub class 建立完畢
JSon class
Sub print
JSon class 建立完畢
---------------
---------------
基類指向子類物件虛擬函式呼叫---------------
Sub print
基類用子類宣告虛擬函式呼叫---------------
Sub print
子類用孫類宣告虛擬函式呼叫---------------
Sub print
0
孫類物件函式呼叫json
Sub print
0
----------------------------------------
基類用孫類虛擬函式呼叫,子類未修改也未顯式宣告
2
子類用孫類虛擬函式呼叫,子類未修改也未顯式宣告
0
顯式刪除子類物件指標---------------
JSon虛構了
Sub虛構了0
Base虛構了
---------------
本程式中JSon被建立的次數是:2
函式行將結束,虛擬解構函式呼叫情況
Sub虛構了0
Base虛構了
Press any key to continue

這裡還有兩點疑惑:

1、在程式自動清除物件之時,不是所有物件的解構函式都被呼叫了,這是為什麼?
2、在我顯式清除所有宣告的物件指標之時,發生了‘記憶體不能讀取’錯我,難道是空指標嗎?