程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> “類名稱”+“::”調用方式,類名稱調用方式

“類名稱”+“::”調用方式,類名稱調用方式

編輯:C++入門知識

“類名稱”+“::”調用方式,類名稱調用方式


注:

對靜態函數或靜態成員的調用方式不做分析;

以下提到的測試環境為vc6.0;

 

調試程序時看到這樣的代碼:

      

1 pObj->ClassName::Function();

 

開始不理解為什麼要在“->”後加上類名“ClassName::”,一般使用中類名稱加“::”(ClassName::)是用來調用靜態函數或靜態成員的,帶著疑問做了下嘗試。

 

定義類A:

復制代碼
 1 class A
 2 {
 3   public: 
 4          void Test()
 5          {
 6               int nVal= 8;
 7               int nVal1 = nVal;
 8           }
 9 
10 };
復制代碼

調用方式:

1 A* pA = NULL;
2 pA->A::Test();

 

測試能夠順利通過。但是調試時進入A類的Test()函數發現this指針為空:

                       

 

修改類A為:

復制代碼
 1 class A
 2 {
 3 public:
 4        A(){ m_nVal = 5; }
 5        ~A(){}
 6 
 7        void Test()
 8        {
 9               int nVal= 8;
10               int nVal1 = nVal;
11               int nVal2 = m_nVal;    //調用成員變量
12 
13       }
14 
15 protected:
16        int m_nVal;  //增加成員變量    
17 
18 };
復制代碼

 

再次執行:

1 A* pA = NULL;
2 pA->A::Test();

這次程序會崩潰,調試發現是在使用成員變量時崩潰,如下圖:

 

 

通過上面的測試初步得出結論,當采用pA->A::Test()這種方式進行調用時,如果Test()函數中沒有使用類的非靜態成員變量,調用的指針(具體的類對象指針this)是否為空可以不考慮,能夠順利通過,如果Test()函數中使用了類的非靜態成員變量,則必須要求調用的指針不為null,也就是必須有已分配了內存空間的類對象,因為這些非靜態成員變量的空間是分配在類對象上的。對於類的靜態成員這裡就不在敘述(因為類的靜態成員屬於類本身,不屬於類對象)。

 

到這裡問題就來了,調用時直接寫成pA->Test()不就可以了,干嘛寫的這麼別扭,給人感覺很深奧的樣子(事實是有點深奧),通過經驗猜測應該和繼承有關系,於是做了如下嘗試:

 

修改類A:

復制代碼
 1 class A
 2 {
 3 public:
 4        A(){ m_nVal = 5; }
 5        ~A(){} 
 6 
 7        virtual void Test()     //變為虛函數
 8        { 
 9            int nVal= 8;
10            int nVal1 = nVal;
11            int nVal2 = m_nVal;
12        }
13 
14 protected:
15        int m_nVal;
16 };
復制代碼

增加類B繼承於類A:

復制代碼
 1 class A
 2 {
 3 public:
 4        A(){ m_nVal = 5; }
 5        ~A(){}
 6 
 7       virtual void Test()     //變為虛函數
 8       {
 9            int nVal= 8;
10            int nVal1 = nVal;
11            int nVal2 = m_nVal;
12       }
13 
14 protected:
15        int m_nVal;
16 };
復制代碼

調用方式:

A* pA = new B;

pA->Test();           //第一步

pA->A::Test();      //第二步

 

調試時發現,當執行第一步時進入的是類B(子類)中定義的Test()函數,執行第二步時進入的是類A(父類)中的Test()函數,第一步調用是實現多態的一種方式很常見,而第二種調用方式是刻意破壞多態的結構,已達到指定的去執行父類的函數,我個人不贊成這種寫法,首先它打破了常規寫法,並且看起來不易理解,也不利於維護擴展,完全可以采取其他常見方式實現相應功能。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved