C++類型轉換(翻譯自cplusplus)

來源:互聯網
上載者:User
前言

  原文翻譯自http://www.cplusplus.com/doc/tutorial/typecasting/,覺得這篇文章講C++類型轉換簡單明了,所以特別翻譯了下。

  在C++中,將一個已知的類型轉換為另一個類型,我們稱呼為類型轉換,本文會介紹C++的各種類型轉換。

隱式轉換

隱式轉換不需要任何操作符,它們會自動執行,當值被賦值到相容類型,就會執行,例如:

short a=2000;
int b;
b=a;

隱式轉換,也包括建構函式和運算子的轉換,例如:

class A {};
class B { public: B (A a) {} };

A a;
B b=a;

 

顯式轉換

C++是一個強型別的語言。許多轉換,需要顯式轉換,例如

short a=2000;
int b;
b = (int) a; // c-like cast notation
b = int (a); // functional notation

 

上述的類型轉換已經滿足了基本類型的轉換了,但是如果應用於類和指標中,代碼可以編譯,但是在運行過程中會出錯。例如

// class type-casting
#include <iostream>
using namespace std;

class CDummy {
float i,j;
};

class CAddition {
int x,y;
public:
CAddition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};

int main () {
CDummy d;
CAddition * padd;
padd = (CAddition*) &d;
cout << padd->result();
return 0;
}

這段代碼會在運行期出錯,在執行padd->result()時異常退出。

傳統明確的類型轉換,可以轉換成任何其他指標類型任何指標,它們指向的類型無關。在隨後的調用成員的結果,會產生一個執行階段錯誤或意外的結果。

 

C++標準轉換運算子

傳統的類和指標的類型轉換,十分不安全,可能會在運行時,由於類型不符異常退出,所以C++提供了四個標準轉換運算子:dynamic_cast, reinterpret_cast, static_cast, const_cast

dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

 

dynamic_cast

dynamic_cast只能用於指標和引用的對象。其目的是確保類型轉換的結果是一個有效完成所請求的類的對象,所以當我們從一個類轉換到這個類的基類,dynamic_cast總是可以成功

class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived

當新的類型不是被轉換的類型的基類,dynamic_cast無法完成指標的轉換,返回NULL,如果dynamic_cast是用來轉換為參考型別的轉換失敗,會拋出"Bad_cast exception"異常。

dynamic_cast 可以轉換NULL指標為不相關的類,也可以任何類型的指標為void指標。 

dynamic_cast的需要的運行時類型資訊(RTTI),保持動態類型跟蹤。一些編譯器支援此功能預設情況下是禁用的選項。這必須啟用運行時類型檢查,使用dynamic_cast的正常工作。

 

static_cast

static_cast可以執行相關的類的指標之間的轉換,不僅從衍生類別到基類的轉換,也可以做到基類到衍生類別的轉換。static_cast沒有在運行時進行安全檢查,因此,它是程式員,以確保轉換是安全的,但是dynamic_cast的型別安全檢查的開銷,static_cast是可以避免的。

class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);

 

上述代碼是合法的,雖然b指向一個不完整的對象,並可能在運行期導致錯誤。

static_cast也可以用來執行任何其他非指標的轉換,例如像基本類型之間的標準轉換,也可以是隱式執行

double d=3.14159265;
int i = static_cast<int>(d);

 

reinterpret_cast

reinterpret_cast轉換成任何其他指標類型,甚至無關的類,任何指標類型。操作的結果是一個簡單的從一個指標到其他的值的二進位拷貝。所有的指標轉換是允許的:不管是指標指向的內容還是指標本身的類型。

同時,它也可以把指標轉換為整數,但是整數是平台相關的,必須保證整數足夠大到可以包含指標本身的內容,最後再轉換為一個合法的指標。

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a)

 

const_cast

const_cast用於操縱對象的常量性,既要設定或刪除。例如,一個函數要求一個非const參數,而程式需要傳遞一個const參數。

#include <iostream>
using namespace std;

void print (char * str)
{
cout << str << endl;
}

int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) );
return 0;
}

 

typeid

typeid的允許檢查運算式的類型
typeid (expression)

 

這個操作符返回一個引用在標準標頭檔<typeinfo>中定義的常量對象,是一個類型的type_info。這個傳回值可以與另一個使用運算子==和!=進行比較兩個資料類型或類的名稱,或者也可以使用其name() 成員函數獲得類型名字(一個0結束的的字串)。

// typeid
#include <iostream>
#include <typeinfo>
using namespace std;

int main () {
int * a,b;
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}

當typeid應用使用RTTI來跟蹤動態對象的類型,那麼當typeid的是應用於運算式,其類型是一個多態類,其結果是派生的最完整的對象的類型:

// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;

class CBase { virtual void f(){} };
class CDerived : public CBase {};

int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " << e.what() << endl; }
return 0;
}

注意:返回的字串成員的type_info名稱取決於你的編譯器和庫的具體實現,其典型的類型名稱,它不一定是一個簡單的字串.

如果類型typeid的參數是引用操作符(*)開頭的指標,而且這個指標是NULL,typeid會拋出一個bad_typeid異常。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.