由static_cast(CMyClass)(*pObject)引發的一系列思考【原創】

問題的引出:
 
typedef list<CMediaFile> CMediaFileList; // 錄像文件鏈表,CMediaFile是定義的一個類
 
 CMediaFileList::iterator it = m_MediaFileList.begin();
 for( ; it != m_MediaFileList.end() ; it++ )
 {
  XTRACE ( "全路徑的文件名:%s,通道號:%d,記錄編號:%d,/n " ,
   (static_cast<CMediaFile>((*it))).sPathName.c_str(),
   (static_cast<CMediaFile>((*it))).nChannel,
   (static_cast<CMediaFile>((*it))).uID
   );
 }
//…………
//上面一段代碼作一個簡單的測試,輸出鏈表的所有內容。
//…………
 CMediaFileList::iterator it = m_MediaFileList.begin();
XTRACE ( "全路徑的文件名:%s", (static_cast<CMediaFile>((*it))).sPathName.c_str() );
//…………
看看結果,第二個trace輸出空的
 
看起來沒什麼錯,呵呵,我也是調試可好長時間。先從下面一個程序講起,最好親手編譯一下:

#include "conio.h"
#include "iostream"
using namespace std;

class CMyClass
{
    public:
     CMyClass()
     {
          cout << "CMyClass::CMyClass()" << endl;
     }
     ~CMyClass()
     {
          cout << "CMyClass::~CMyClass()" << endl;
     }

     void Draw()
     {
          cout << "CMyClass::Draw()" << endl;
     }
};

int _tmain(int argc, _TCHAR* argv[])
{
     CMyClass * pObject = new CMyClass;

     static_cast<CMyClass>(*pObject).Draw();

     delete pObject;
     _getch();

     return 0;
}
// 輸出結果如下:
CMyClass::CMyClass()
CMyClass::Draw()
CMyClass::~CMyClass()
CMyClass::~CMyClass()
 
在看看代碼,static_cast<CMyClass>是否覺得有某些災難!原因何在,因爲在類型轉換的時候自動構造和析構了一個CMyClass對象。爲什麼沒有我們定義的構造輸出而有析構輸出呢?
因爲這裏的類型轉換構造使用了拷貝構造函數。
一般情況下,如果類不特殊聲明函數,系統自動爲我們產生四個函數:
1.構造
2.析構
3.拷貝構造函數(注意了)
4.重載=操作符,大致是cmyclass operator = (const cmyclass & object){…………}
 
上面我們沒有定義拷貝構造函數,當然不會輸出:CMyClass::CMyClass()  了。
下面我們來自定義一個拷貝構造函數(加爲成員函數):
 CMyClass(const CMyClass & object)
 {
    cout << "CMyClass::CMyClass(const CMyClass & object)" << endl;
 }
在看看輸出:
CMyClass::CMyClass()
CMyClass::CMyClass(const CMyClass & object)
CMyClass::Draw()
CMyClass::~CMyClass()
CMyClass::~CMyClass()
 
呵呵,這回如我們所願了。
再看看程序有沒有優化的地方?使用引用和指針效率會更高:
static_cast<CMyClass*>(pObject)->Draw();
static_cast<CMyClass &>(*pObject).Draw();
就只有一個輸出了(沒有拷貝構造和析構),結果如下:
CMyClass::CMyClass()
CMyClass::Draw()
CMyClass::~CMyClass()
 
現在我們回過頭來看看:爲什麼喜歡用static_cast這個咚咚呢,有什麼好處?
我用(CMyClass&)(*pObject).Draw();工作不是挺好的???
 
static_cast :一般情況下就用它, 功能上基本上與C風格的類型轉換一樣,含義也一樣
reinterpret_cast : 用於將一種類型的值解釋爲另一種類型的值 ,很少使用
const_cast去掉某個對象或指針的const或volatileness屬性
dynamic_cast轉換的目標類型限於類的指針或引用,被轉換的類必須是多態類
 
是c99引入的東西,使用它們至少有2個好處:
 
一是其本身就是一種註釋,在代碼中看到上面這些關鍵字就可馬上知道此處是進行類型轉換。二是C語言中類型轉換通常是很難進行搜索的,而通過關鍵字cast則可以很容易的找到程序中出現類型轉換的地方了。

強制類型轉換

    程序員可以在表達式中使用3種強制類型轉換表達式:

    ① (T)E; //C語言中所使用的風格,如 (int)x;

    ② T(E); //C++語言中所使用的風格,類似於函數調用, 如 int(x);

    ③ cast_operator<T>(E); //C++語言提供的4種類型轉換的新形式

大家可在實踐中多多摸索,我也是個菜鳥,呵呵。雞蛋,石頭@%$#@^%#@$#^$,我閃~
發佈了41 篇原創文章 · 獲贊 1 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章