詳解C++?轉(zhuǎn)換的非正式分類
C++ 正式分類方法是直接按語法分類,分為:隱式轉(zhuǎn)換和顯示轉(zhuǎn)換。隱式轉(zhuǎn)換又稱為標(biāo)準(zhǔn)轉(zhuǎn)換。顯示轉(zhuǎn)換又分為:C 風(fēng)格轉(zhuǎn)換、函數(shù)風(fēng)格轉(zhuǎn)換、C++ 風(fēng)格轉(zhuǎn)換。C++風(fēng)格轉(zhuǎn)換就是 static_cast、dynamic_cast、const_cast 和 reinterpret_cast 這 4 種。
有很長一段時間我都有這樣的疑問:轉(zhuǎn)換前的對象和轉(zhuǎn)換后的對象是不是同一個?
現(xiàn)在,我引入一種非正式分類方法,分為:同對象轉(zhuǎn)換和異對象轉(zhuǎn)換。這兩個術(shù)語是我自己編的,只是為了方便說明問題。
- 同對象轉(zhuǎn)換:轉(zhuǎn)換后的對象和轉(zhuǎn)換前的對象是同一個,也就是不會構(gòu)造一個新的對象,還是使用原來的對象。
- 異對象轉(zhuǎn)換:轉(zhuǎn)換后的對象和轉(zhuǎn)換前的對象不是同一個,也就是會構(gòu)造一個新的的對象。
下面分別說明這兩種轉(zhuǎn)換的典型情況。
一、同對象轉(zhuǎn)換
所有的值類別轉(zhuǎn)換及其變形都是同對象轉(zhuǎn)換。
1. 值類別轉(zhuǎn)換
C++ 的值類別可以使用 static_cast 進行轉(zhuǎn)換,屬于同對象轉(zhuǎn)換。注意:static_cast<T&>() 和 static_cast<T&&>() 的語義不是將一個對象轉(zhuǎn)換為一個引用,而是轉(zhuǎn)換對象的值類別,使其能被對應(yīng)的引用綁定。
// 左值轉(zhuǎn)換為左值 int a = 1; static_cast<int&>(a) = 2; std::cout << a << std::endl; // 輸出:2
// 左值轉(zhuǎn)換為右值 int a = 1; int&& b = static_cast<int&&>(a); b = 2; std::cout << a << std::endl; // 輸出:2
// 右值轉(zhuǎn)換為右值,轉(zhuǎn)換前對象為非字面量 int a = 1; int&& b = static_cast<int&&>(static_cast<int&&>(a)); b = 2; std::cout << a << std::endl; // 輸出:2
2. 借助值類別轉(zhuǎn)換進行 OOP 轉(zhuǎn)換
這種情況帶有值類別轉(zhuǎn)換,屬于同對象轉(zhuǎn)換。
// upcast
struct A
{
int x = 1;
};
struct B : A
{
};
B b;
static_cast<A&>(b).x = 2;
std::cout << b.x << std::endl;
// 輸出:2// downcast
struct A
{
int x = 1;
};
struct B : A
{
};
B b;
static_cast<B&>(static_cast<A&>(b)).x = 2;
std::cout << b.x << std::endl;
// 輸出:2// sidecast
struct A1
{
virtual void f1() {}
int x = 1;
};
struct A2
{
virtual void f2() {}
int y = 1;
};
struct B : A1, A2
{
};
B b;
dynamic_cast<A2&>(static_cast<A1&>(b)).y = 2;
std::cout << b.y << std::endl;
// 輸出:22. 借助值類別轉(zhuǎn)換進行 const_cast 轉(zhuǎn)換
這種情況帶有值類別轉(zhuǎn)換,也是同對象轉(zhuǎn)換。注意:通過 const_cast 修改原本為 const 的對象是未定義行為。
struct A
{
int x = 1;
};
{
int a;
const_cast<int&>(const_cast<const int&>(a)) = 2;
std::cout << a << std::endl;
}
{
A a;
const_cast<A&>(const_cast<const A&>(a)).x = 2;
std::cout << a.x << std::endl;
}
/* 輸出:
2
2
*/二、異對象轉(zhuǎn)換
所有的非值類別轉(zhuǎn)換都是異對象轉(zhuǎn)換。
1. 普通的類型轉(zhuǎn)換
// 標(biāo)量類型 int a = 1; int&& b = static_cast<int>(a); b = 2; std::cout << a << std::endl; // 輸出:1
// 類類型
struct A
{
A() {
std::cout << "A::A() " << x << std::endl;
}
A(const A&) {
std::cout << "A::A(const A&) " << x << std::endl;
}
~A() {
std::cout << "A::~A() " << x << std::endl;
}
int x = 1;
};
A a;
A&& b = static_cast<A>(a);
b.x = 2;
std::cout << b.x << std::endl;
/* 輸出:
A::A() 1
A::A(const A&) 1
2
A::~A() 2
A::~A() 1
*/2. 指針轉(zhuǎn)換
轉(zhuǎn)換之后,指針本身是異對象,指針?biāo)傅膶ο笫峭瑢ο?。這種情況也包含:借助指針進行 OOP 轉(zhuǎn)換,借助指針進行 const_cast 轉(zhuǎn)換。
int* a = new int; std::cout << a << std::endl; int* && r = static_cast<int*>(a); r = nullptr; std::cout << a << std::endl; /* 輸出: 0x1ffdeb0 0x1ffdeb0 */
到此這篇關(guān)于C++ 轉(zhuǎn)換的非正式分類的文章就介紹到這了,更多相關(guān)C++ 轉(zhuǎn)換非正式分類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實現(xiàn)大學(xué)生考勤管理系統(tǒng)
這篇文章主要為大家詳細介紹了C語言實現(xiàn)大學(xué)生考勤管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-12-12
C語言中一些將字符串轉(zhuǎn)換為數(shù)字的函數(shù)小結(jié)
這篇文章主要介紹了C語言中一些將字符串轉(zhuǎn)換為數(shù)字的函數(shù)小結(jié),分別為atoi()函數(shù)和atol()函數(shù)以及atof()函數(shù),需要的朋友可以參考下2015-08-08

