摘要:不能進(jìn)行隱式轉(zhuǎn)換跟它相對(duì)應(yīng)的另一個(gè)關(guān)鍵字是,意思是隱藏的,類構(gòu)造函數(shù)默認(rèn)情況下即聲明為隱式。通過(guò)排他性來(lái)定義,每個(gè)表達(dá)式不是就是。返回容器中倒數(shù)第一個(gè)元素的常量迭代器。這種轉(zhuǎn)換的安全性也要開(kāi)發(fā)人員來(lái)保證。
目錄
5.2.reinterpreter_cast 轉(zhuǎn)換
?explicit???/?k?spl?s?t/???明確的;清楚的;直率的;詳述的
作用是表明該構(gòu)造函數(shù)是顯示的, 而非隱式的。不能進(jìn)行隱式轉(zhuǎn)換!跟它相對(duì)應(yīng)的另一個(gè)關(guān)鍵字是implicit,意思是隱藏的,類構(gòu)造函數(shù)默認(rèn)情況下即聲明為implicit(隱式)。
例如我們定義一個(gè)類
class student {public: student(int age) { this->age = age; cout << "age=" << age << endl; } student(int age, string name) { this->age = age; this->name = name; cout << "age=" << age << " name=" << name << endl; } ~student() { } int getAge() { return this->age; } string getName() { return this->name; }private: string name; int age;};
在主函數(shù)中分別使用顯示構(gòu)造和隱式構(gòu)造
int main() { //顯示構(gòu)造,直接在括號(hào)里面寫 student xiaoM(18); //顯示構(gòu)造 student xiaoH(19, "小花"); //隱式構(gòu)造 student xiaoW = 18; //隱式構(gòu)造(C++11前編譯器無(wú)法通過(guò)) student xiaoZ = { 19,"小張" }; system("pause"); return 0;}
執(zhí)行結(jié)果
當(dāng)給其中一個(gè)構(gòu)造函數(shù)加上explicit關(guān)鍵字后
class student {public: explicit student(int age) { this->age = age; cout << "age=" << age << endl; }private: string name; int age;};
這種聲明就表示:這個(gè)構(gòu)造函數(shù)只能顯示構(gòu)造,無(wú)法進(jìn)行隱式轉(zhuǎn)換
explicit關(guān)鍵字的作用在于:在實(shí)際開(kāi)發(fā)中 等號(hào)會(huì)產(chǎn)生一些歧義,等號(hào)本身又有賦值的作用,無(wú)法在一瞬間辨別等號(hào)是用于賦值還是調(diào)用隱式構(gòu)造,不便于閱讀。
我們?cè)谌粘>幾g程序時(shí),有時(shí)可能會(huì)遇到如下報(bào)錯(cuò)提示:
源代碼
#includeusing namespace std;int demo() { int i = 0; return i;}int main() { //將函數(shù)返回作為左值 demo() = 888; return 0;}
這里將函數(shù)返回賦予888,編譯器給出“表達(dá)式必須是可修改的左值”的報(bào)錯(cuò)提示 ,如果我們將函數(shù)返回作為右值,則不會(huì)有此報(bào)錯(cuò)~
關(guān)于左值和右值的問(wèn)題,這里就涉及到計(jì)算機(jī)的存儲(chǔ)層次結(jié)構(gòu)
?存儲(chǔ)層次結(jié)構(gòu)
例如我們計(jì)算 c = a + b ;
a 和 b 的值會(huì)保存在內(nèi)存中,當(dāng)程序遇到c = a + b,會(huì)將a和b的值拿到cpu的寄存器中,再將計(jì)算結(jié)果返回給內(nèi)存中的c,當(dāng)我們Ctrl + S后,內(nèi)存中的數(shù)據(jù)就可以永久保存到磁盤中。
?左值和右值的概念
?按字面意思,通俗地說(shuō)。以賦值符號(hào) = 為界,等號(hào)(=)左邊的就是左值(lvalue),等號(hào)(=) 右邊就是右值(rvalue)。??
lvalue —— 代表一個(gè)在內(nèi)存中占有確定位置的對(duì)象(換句話說(shuō)就是有一個(gè)地址)。?
rvalue —— 通過(guò)排他性來(lái)定義,每個(gè)表達(dá)式不是lvalue就是rvalue。因此從上面的 ? lvalue的定義,rvalue是在不在內(nèi)存中占有確定位置的表達(dá)式,而是存在在寄存器中。
所有的左值(無(wú)論是數(shù)組,函數(shù)或不完全類型)都可以轉(zhuǎn)換成右值。
?我們將下面程序轉(zhuǎn)為匯編碼觀察
#includeusing namespace std;int main() { int a = 1; int b = 2; int c = 3; c = a + b; printf("%d", c); return 0;}
匯編代碼
程序?qū)、b、c的值都存儲(chǔ)在棧上,當(dāng)執(zhí)行 c= a + b 時(shí),程序會(huì)將 a 和 b 的值拿到寄存器中計(jì)算,再將計(jì)算結(jié)果返回給內(nèi)存中 c 的位置上去。
也就是說(shuō),程序執(zhí)行的方式,是從內(nèi)存中取值放到寄存器中,再將計(jì)算結(jié)果返回給內(nèi)存中的某個(gè)位置!
a + b的結(jié)果保存在寄存器中,再將寄存器的值返回給內(nèi)存
因此,對(duì)于? c = a + b;是合法的
而 a + b = c;也就是eax = c就是非法,左值需要在內(nèi)存中有位置,而a + b是在寄存器?? 中
?上面我們講了左值與右值,當(dāng)我們把函數(shù)返回值作為左值時(shí),編譯器給出報(bào)錯(cuò)提示,而C++11的新增特性“函數(shù)返回引用”又可以實(shí)現(xiàn)函數(shù)返回值作為左值的操作
C++引用使用時(shí)的難點(diǎn):
1.當(dāng)函數(shù)返回參數(shù)是引用時(shí)
????????? 若返回棧變量(自動(dòng)變量/臨時(shí)變量),不能成為其它引用的初始值,不能作為左值使用。
2. 若返回靜態(tài)變量或全局變量
??????? ·可以成為其他引用的初始值
??????? ·即可作為右值使用,也可作為左值使用
? 3. ??返回形參當(dāng)引用
??????? (注:C++鏈?zhǔn)骄幊讨?,?jīng)常用到引用,運(yùn)算符重載專題) 例如在重載“<<"左移運(yùn)算符后,我們想要鏈?zhǔn)捷敵?,就是返回的cout引用
下面,對(duì)第一種種情況分別通過(guò)代碼舉例 ?
1. 函數(shù)返回值為引用,返回臨時(shí)變量作為其他引用的初始值
#includeusing namespace std;int& demo() { int i = 600; return i; //返回局部變量 }int main() { int &a =demo(); //函數(shù)引用成為其他引用的初始值 cout << a << endl; system("pause"); return 0;}
編譯結(jié)果
編譯器并未報(bào)錯(cuò),也只是給出警告 “ 返回局部變量 ” 。好像目測(cè)也沒(méi)啥問(wèn)題 ,下面通過(guò)一段代碼示例,來(lái)解釋這種操作的不合理性。?看操作。
我們知道,通過(guò)引用可以將兩個(gè)變量都有同一塊地址
?
因此,對(duì)于上面的代碼,a 的地址和局部變量 i 有相同的地址
?
?我們現(xiàn)在更改a的值,然后再調(diào)用demo函數(shù)
int main() { int &a = demo(); cout << "a的地址為:" <<&a<
運(yùn)行結(jié)果:
第一次demo函數(shù)執(zhí)行,i 的地址為00D3F854,a的地址也為00D3F854。
然后demo函數(shù)執(zhí)行完畢后,在棧內(nèi)的空間釋放。
第二次demo函數(shù)也是在棧的相同位置存儲(chǔ),所以 i 的位置沒(méi)有改變,因此 i =600后也影響了a的值。
?
如果我們?cè)跅V惺褂脙蓚€(gè)函數(shù),會(huì)是什么結(jié)果呢?
#include#includeusing namespace std;int demo1() { int i = 100; cout << "demo1()函數(shù)中,i的地址為:" << &i << endl; return 0;}int& demo() { int i = 600; cout << "i的地址為:" << &i << endl; return i; //返回局部變量}int main() { int &a = demo(); cout << "a的地址為:" <<&a<
執(zhí)行結(jié)果
也就是說(shuō),如果用函數(shù)返回引用,返回局部變量和引用初始化,程序會(huì)繼續(xù)認(rèn)為這個(gè)地址還是屬于計(jì)算機(jī)的,并非是程序員自己申請(qǐng)的。
2.返回局部變量作為左值
?情況與上面類似
#include#includeusing namespace std;int demo1() { int i = 0; cout << "demo1()函數(shù)中,i的地址為:" << &i << endl; return 0;}int& demo(int **p) { int i = 600; *p = &i; cout << "i的地址為:" << &i << " i的值為:" << i << endl; return i; //返回局部變量}int main() { int* p = NULL; demo(&p) = 888; cout << "p的地址為:" << p << " p的值為:" << *p << endl; demo1(); cout << "p的地址為:" << p << " p的值為:" << *p << endl; system("pause"); return 0;}
執(zhí)行結(jié)果
?總結(jié):若返回棧變量(自動(dòng)變量/臨時(shí)變量),不能成為其它引用的初始值,不能作為左值使用,雖然編譯器只會(huì)警告,但在實(shí)際開(kāi)發(fā)中是非常危險(xiǎn)的操作!
3.例如返回static或者全局變量就不出出現(xiàn)這種情況
#include#includeusing namespace std;int& demo() { static int i = 600; cout << "i的地址為:" << &i << endl; return i; //返回靜態(tài)變量}int main() { int a = demo(); a = 888; cout << "調(diào)用了demo(),a的值為:" << a << endl; demo(); cout << "再次調(diào)用了demo(),a的值為:" << a << endl; system("pause"); return 0;}
執(zhí)行結(jié)果
其實(shí),主要還是看返回值的生命周期,如果是立刻銷毀的,則應(yīng)注意使用~
?array容器概念?
- array 容器是?C++?11 標(biāo)準(zhǔn)中新增的序列容器,簡(jiǎn)單地理解,它就是在 C++ 普通數(shù)組的基礎(chǔ)上,添加了一些成員函數(shù)和全局函數(shù)。
- array是將元素置于一個(gè)固定數(shù)組中加以管理的容器。
- array可以隨機(jī)存取元素,支持索引值直接存取, 用[]操作符或at()方法對(duì)元素進(jìn)行操作,也可以使用迭代器訪問(wèn)
- 不支持動(dòng)態(tài)的新增刪除操作
- array可以完全替代C語(yǔ)言中的數(shù)組,使操作數(shù)組元素更加安全!
- #include
?array特點(diǎn)
- array 容器的大小是固定的,無(wú)法動(dòng)態(tài)的擴(kuò)展或收縮,這也就意味著,在使用該容器的過(guò)程無(wú)法增加或移除元素而改變其大小,它只允許訪問(wèn)或者替換存儲(chǔ)的元素。
- STL?還提供有可動(dòng)態(tài)擴(kuò)展或收縮存儲(chǔ)空間的 vector 容器
?array對(duì)象的構(gòu)造
?array采用模板類實(shí)現(xiàn),array對(duì)象的默認(rèn)構(gòu)造形式
array
arrayT; ???//T為存儲(chǔ)的類型, 為數(shù)值型模板參數(shù) //構(gòu)造函數(shù)
#include
array a1; //一個(gè)存放5個(gè)int的array容器array a2; //一個(gè)存放6個(gè)float的array容器array a3; //一個(gè)存放7個(gè)student的array容器
?array的賦值
array?的賦值
a1.assign(0); //玩法一?改變array中所有元素(注:將被廢棄,不推薦使用)
在目前版本,編譯器會(huì)報(bào)錯(cuò)
如果非要使用assign的話可以根據(jù)報(bào)錯(cuò)提示加一個(gè)宏
#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING 1
a1.fill(666); //玩法二 用特定值填充array中所有元素
array
test={1, 2, 3, 4};// 玩法三 定義時(shí)使用初始化列表,列表內(nèi)的數(shù)量不能超過(guò)定義的大小
array
test; test={1,2,3,4}; ??//玩法四 定義后使用列表重新賦值
array
a1,a2; a1={1,2,3,4};
a2 = a1;//玩法五,賦值運(yùn)算
a1.swap(a2); ?//玩法六 ?和其它array進(jìn)行交換
?array的大小
array.size(); 返回容器中元素的個(gè)數(shù)array.empty(); 判斷容器是否為空,逗你玩的,因?yàn)槿萜魇枪潭ù笮。肋h(yuǎn)為 falsearray.max_size(); 返回容器中最大元素的個(gè)數(shù),數(shù)組是固定大小,這也是逗你玩的同size()。
array的數(shù)據(jù)存取 ?
第一 ?使用下標(biāo)操作 a1[0] = 100;
第二 ?使用at 方法 如: a1.at(2) = 100;
第三 ?接口返回的引用 a1.front() 和 a1.back() ?
注意: ??第一和第二種方式必須注意越界
array 迭代器訪問(wèn)?
#include
using namespace std;array.begin(); 返回容器中第一個(gè)數(shù)據(jù)的迭代器。array.end(); 返回容器中最后一個(gè)數(shù)據(jù)之后的迭代器。array.rbegin(); 返回容器中倒數(shù)第一個(gè)元素的迭代器。array.rend(); 返回容器中倒數(shù)最后一個(gè)元素的后面的迭代器。array.cbegin(); 返回容器中第一個(gè)數(shù)據(jù)的常量迭代器。array.cend(); 返回容器中最后一個(gè)數(shù)據(jù)之后的常量迭代器。array.crbegin(); 返回容器中倒數(shù)第一個(gè)元素的常量迭代器。array.crend(); 返回容器中倒數(shù)最后一個(gè)元素的后面的常量迭代器。 #include
#include using namespace std;int main() { array arrayInt = { 1,2,3,4,5 }; 普通迭代器 for (array ::iterator ite = arrayInt.begin(); ite != arrayInt.end(); ite++) cout << *ite << " "; 常量迭代器,常量迭代器無(wú)法修改 array ::const_iterator ite = arrayInt.cbegin(); 逆向迭代器,逆向迭代器也是++ for (array ::reverse_iterator ite = arrayInt.rbegin(); ite != arrayInt.rend(); ite++) cout << *ite << " ";} set.rbegin()與set.rend()。略。
舊式轉(zhuǎn)型? C風(fēng)格的強(qiáng)制類型
??????????????? type? b? =? (? type? )? a
??????????????? 例如:
??????????????? int i = 48;
??????????????? char? c = (char ) i;
double PI = 3.1415926;int i = PI; 隱式轉(zhuǎn)換int i1 = (int) PI ; 強(qiáng)制類型轉(zhuǎn)換強(qiáng)制類型轉(zhuǎn)換,整數(shù)直接變指針int * addr = (int*) 0x888888; void *p;int * int_arg = (int*) p; 強(qiáng)制轉(zhuǎn)換
?
?
新式轉(zhuǎn)型C++風(fēng)格的類型轉(zhuǎn)換提供了4種類型轉(zhuǎn)換操作符來(lái)應(yīng)對(duì)不同場(chǎng)合的應(yīng)用。
格式:
??? type b?= 類型操作符<type> (?a?)???
???????類型操作符= static_cast | reinterpreter_cast | dynamic_cast | const_cast
?
靜態(tài)類型轉(zhuǎn)換(斯文的勸導(dǎo),溫柔的轉(zhuǎn)換)(編譯器會(huì)檢查轉(zhuǎn)換是否合理)。如int轉(zhuǎn)換成char
char a = "A";int b = static_cast
(a); 主要用法:
- 用于類層次結(jié)構(gòu)中基類(父類)和派生類(子類)之間指針或引用的轉(zhuǎn)換。上行指針或引用(派生類到基類)轉(zhuǎn)換安全,下行不安全(上行可以,下行不安全)
- 用于基本數(shù)據(jù)類型之間的轉(zhuǎn)換,如把int轉(zhuǎn)換成char,把int轉(zhuǎn)換成enum。這種轉(zhuǎn)換的安全性也要開(kāi)發(fā)人員來(lái)保證。
- 把空指針轉(zhuǎn)換成目標(biāo)類型的空指針。
- 把任何類型的表達(dá)式轉(zhuǎn)換成void類型
?
1.用于類層次結(jié)構(gòu)中基類(父類)和派生類(子類)之間指針或引用的轉(zhuǎn)換?
class Animal {public: virtual void cry() = 0;};class dog :public Animal {public: void cry() { cout << "小狗汪汪汪" << endl; }};int main() { dog* d = new dog(); Animal* animal = d;//子類對(duì)象賦給基類 使用static_cast指針轉(zhuǎn)換 Animal* al = static_cast(d); 引用轉(zhuǎn)換 dog d2; Animal& a2 = static_cast(d2); system("pause"); return 0;}
那為什么說(shuō)上行轉(zhuǎn)換可以,下行轉(zhuǎn)換不安全呢?
我們?cè)僭黾右粋€(gè)Animal的派生類
class cat :public Animal {public: void cry() { cout << "小貓喵喵喵" << endl; }};
int main() { dog* d = new dog(); //上行轉(zhuǎn)換安全 Animal* animal = static_cast(d); //下行轉(zhuǎn)換,這種也是安全的 d = static_cast(animal); //animal已經(jīng)是dog類轉(zhuǎn)過(guò)來(lái)的,再轉(zhuǎn)成cat的就不安全的 cat* c; c = static_cast(animal); system("pause"); return 0;}
因此,并不是說(shuō)下行轉(zhuǎn)換不可用,例如上面的將從dog類轉(zhuǎn)過(guò)來(lái)的animal再轉(zhuǎn)到cat就是不安全的,還是取決于程序員的使用 。
2.基本數(shù)據(jù)類型之間的轉(zhuǎn)換?
int a = 10;char b = static_cast(a);
?3.把空指針轉(zhuǎn)換成目標(biāo)類型的空指針。
int* p = static_cast
(NULL); NULL在C++里定義的是void*0
?4.把任何類型的表達(dá)式轉(zhuǎn)換成void類型
int* p = new int[10];void* vp = static_cast(p);
總結(jié):使用static_cast可以使編譯器做一些合法性檢查,不寫也沒(méi)關(guān)系。
?
重新解釋類型(掛羊頭,賣狗肉)?不同類型間的互轉(zhuǎn),數(shù)值與指針間的互轉(zhuǎn)
用法: ?
??????? type b?= reinterpret_cast
( ?a?)????????type 必須是一個(gè)指針、引用、算術(shù)類型、函數(shù)指針。
例如強(qiáng)制將整數(shù)轉(zhuǎn)為指針int* addr = reinterpret_cast
(0x88888);如果使用static_cast則會(huì)報(bào)錯(cuò)int* addr1 = static_cast (0x88888); ?
?
忠告:濫用 reinterpret_cast 運(yùn)算符可能很容易帶來(lái)風(fēng)險(xiǎn)。 除非所需轉(zhuǎn)換本身是低級(jí)別的,否則應(yīng)使用其他強(qiáng)制轉(zhuǎn)換運(yùn)算符之一。
用法1,數(shù)值與指針之間轉(zhuǎn)換?
int* p = reinterpret_cast(0x88888);int val = reinterpret_cast(p);
用法2, 不同類型指針和引用之間的轉(zhuǎn)換
?定義一個(gè)父類和兩個(gè)派生類
class Animal {public: void cry() { cout << "動(dòng)物叫" << endl; }};class cat :public Animal {public: void cry() { cout << "小貓喵喵喵" << endl; }};class dog :public Animal {public: void cry() { cout << "小狗汪汪汪" << endl; }};
1.隱式上行? 轉(zhuǎn)換? 與強(qiáng)制上行? 轉(zhuǎn)換
dog d1;Animal* animal = &d1;animal->cry();//如果能用static_cast強(qiáng)轉(zhuǎn),static_cast優(yōu)先dog* d2 = reinterpret_cast(animal);dog* d3 = static_cast(animal);
?2.不同類型指針轉(zhuǎn)換不能用static_cast
?
?
3.但是可以使用reinterpre_cast轉(zhuǎn)換
int main() { dog d1; cat* c1 = reinterpret_cast(&d1); c1->cry(); system("pause"); return 0;}
編譯器不管程序是將什么類型轉(zhuǎn)的,只曉得最后要獲得一個(gè)cat類型,然后按cat的存儲(chǔ)類型,訪問(wèn)里面的方法。如果濫用reinterpreter_cast,類型之間轉(zhuǎn)來(lái)轉(zhuǎn)去,可能會(huì)導(dǎo)致程序快速崩潰。
4.引用的強(qiáng)制類型轉(zhuǎn)換
dog d1;Animal& animal = d1;dog& d2 = reinterpret_cast(animal);
?
?reinterpreter_cast? 再加一個(gè) static_cast 就已經(jīng)可以替換C語(yǔ)言的轉(zhuǎn)換
?
?動(dòng)態(tài)類型轉(zhuǎn)換
- 將一個(gè)基類對(duì)象指針cast到繼承類指針,dynamic_cast 會(huì)根據(jù)基類指針是否真正指向繼承類指針來(lái)做相應(yīng)處理。失敗返回null,成功返回正常cast后的對(duì)象指針;
- 將一個(gè)基類對(duì)象引用cast 繼承類對(duì)象,dynamic_cast 會(huì)根據(jù)基類對(duì)象是否真正屬于繼承類來(lái)做相應(yīng)處理。失敗拋出異常bad_cast
注意:dynamic_cast在將父類cast到子類時(shí),父類必須要有虛函數(shù)一起玩。
?
第一種情況 示例代碼
#includeusing namespace std;class Animal {public: //父類必須有虛函數(shù) virtual void cry() = 0;};class cat :public Animal {public: void cry() { cout << "小貓喵喵喵" << endl; }};class dog :public Animal {public: void cry() { cout << "小狗汪汪汪" << endl; }};int main() { dog d1; Animal* animal = &d1; cat* ca= dynamic_cast(animal); if (ca==NULL) { cout << "這是只狗!" << endl; } else { cout << "這是只貓" << endl; } system("pause"); return 0;}
運(yùn)行結(jié)果
?
第二種情況示例代碼
int main() { dog d1; Animal& animal = d1; dog& d2 = dynamic_cast(animal); system("pause"); return 0;}
這種是沒(méi)有任何問(wèn)題,因?yàn)閐og與animal是子類與父類的關(guān)系,并且animal指針真正指向dog。
但是,如果我們用其他類型接受又會(huì)是什么情況呢?
int main() { dog d1; Animal& animal = d1; cat& d2 = dynamic_cast(animal); system("pause"); return 0;}
基類指針并沒(méi)有指向cat,這種情況編譯是沒(méi)有任何問(wèn)題,因?yàn)榫幾g器會(huì)認(rèn)為這是父類與子類之間的轉(zhuǎn)換,但是當(dāng)我們運(yùn)行時(shí),編譯器就會(huì)拋出異常?
?
?
對(duì)于拋出異常,我們就可以利用try—catch語(yǔ)句捕獲異常,保證程序能繼續(xù)運(yùn)行
int main() { dog d1; Animal& animal = d1; try { cat& d2 = dynamic_cast(animal); } catch (std::bad_cast bc) { cout << "不是貓,應(yīng)該是狗" << endl; } system("pause"); return 0;}
運(yùn)行結(jié)果
?
去const屬性。(僅針對(duì)于指針和引用)?
?例如
#includeusing namespace std;void demo(const char* p) { char* p1 = const_cast(p); p1[0] = "A";}int main() { //字符數(shù)組 char p[] = "1234567"; demo(p); cout << p << endl; system("pause"); return 0;}
運(yùn)行結(jié)果
或者直接使用const_cast,運(yùn)行結(jié)果也是一樣
int main() { char p[] = "1234567"; const_cast(p)[0] = "A"; cout << p << endl; system("pause"); return 0;}
?但是,對(duì)于常量字符串不能去掉const修改
例如
#includeusing namespace std;void demo(const char* p) { char* p1 = const_cast(p); p1[0] = "A";}int main() { const char *p = "1234567"; demo(p); cout << p << endl; system("pause"); return 0;}
可以編譯,但是運(yùn)行會(huì)報(bào)錯(cuò)
因?yàn)槌A克幬恢檬浅A繀^(qū),內(nèi)存無(wú)法訪問(wèn)常量區(qū)。
?
?5.2 類型轉(zhuǎn)換使用建議
1)static_cast靜態(tài)類型轉(zhuǎn)換,編譯的時(shí)c++編譯器會(huì)做編譯時(shí)的類型檢查;隱式轉(zhuǎn)換;
基本類型轉(zhuǎn)換,父子類之間合理轉(zhuǎn)換
2)若不同類型之間,進(jìn)行強(qiáng)制類型轉(zhuǎn)換,用reinterpret_cast<>() 進(jìn)行重新解釋
???建 ?議:
????????C語(yǔ)言中 ?能隱式類型轉(zhuǎn)換的,在c++中可用 static_cast<>()進(jìn)行類型轉(zhuǎn)換。因C++編譯器在編譯檢查一般都能通過(guò);C語(yǔ)言中不能隱式類型轉(zhuǎn)換的,在c++中可以用 reinterpret_cast<>() 進(jìn)行強(qiáng)制類型解釋。
????????總結(jié):static_cast<>()和reinterpret_cast<>() 基本上把C語(yǔ)言中的 強(qiáng)制類型轉(zhuǎn)換給覆蓋,注意reinterpret_cast<>()很難保證移植性。
3)dynamic_cast<>(),動(dòng)態(tài)類型轉(zhuǎn)換,安全的虛基類和子類之間轉(zhuǎn)換;運(yùn)行時(shí)類型檢查
4)const_cast<>(),去除變量的只讀屬性
最后的忠告:程序員必須清楚的知道: 要轉(zhuǎn)的變量,類型轉(zhuǎn)換前是什么類型,類型轉(zhuǎn)換 后是什么類型,轉(zhuǎn)換后有什么后果。
C++大牛建議:一般情況下,不建議進(jìn)行類型轉(zhuǎn)換;避免進(jìn)行類型轉(zhuǎn)換。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/125067.html
摘要:今天逛了逛,順手精選出了一下近幾個(gè)月以來(lái)上最熱門的個(gè)項(xiàng)目。相關(guān)閱讀正式開(kāi)源,幫助應(yīng)用快速容器化未來(lái)可能會(huì)上熱門的項(xiàng)目地址介紹哈哈,皮一下很開(kāi)心。這是我自己開(kāi)源的一份文檔,目前仍在完善中,歡迎各位英雄好漢一起完善。 showImg(https://segmentfault.com/img/remote/1460000015766827?w=391&h=220);今天逛了逛Github,順...
showImg(https://segmentfault.com/img/remote/1460000019961426); 今天在 Apache Flink meetup ·北京站進(jìn)行 Flink 1.9 重大新特性進(jìn)行了講解,兩位講師分別是 戴資力/楊克特,zhisheng 我也從看完了整個(gè) 1.9 特性解讀的直播,預(yù)計(jì) Flink 1.9 版本正式發(fā)布時(shí)間大概是 7 月底 8 月初左右正式發(fā)...
摘要:媒體查詢,添加自,允許內(nèi)容的呈現(xiàn)針對(duì)一個(gè)特定范圍的輸出設(shè)備而進(jìn)行裁剪,而不必改變內(nèi)容本身。而且瀏覽器也不會(huì)根據(jù)媒體查詢來(lái)動(dòng)態(tài)的加載樣式,它只是一股腦的將所有的樣式引入。 簡(jiǎn)介 媒體查詢(Media Queries)早在在css2時(shí)代就存在,經(jīng)過(guò)css3的洗禮后變得更加強(qiáng)大bootstrap的響應(yīng)式特性就是從此而來(lái)的. 簡(jiǎn)單的來(lái)講媒體查詢是一種用于修飾css何時(shí)起作用的語(yǔ)法. Media...
摘要:媒體查詢,添加自,允許內(nèi)容的呈現(xiàn)針對(duì)一個(gè)特定范圍的輸出設(shè)備而進(jìn)行裁剪,而不必改變內(nèi)容本身。而且瀏覽器也不會(huì)根據(jù)媒體查詢來(lái)動(dòng)態(tài)的加載樣式,它只是一股腦的將所有的樣式引入。 簡(jiǎn)介 媒體查詢(Media Queries)早在在css2時(shí)代就存在,經(jīng)過(guò)css3的洗禮后變得更加強(qiáng)大bootstrap的響應(yīng)式特性就是從此而來(lái)的. 簡(jiǎn)單的來(lái)講媒體查詢是一種用于修飾css何時(shí)起作用的語(yǔ)法. Media...
閱讀 1139·2021-11-25 09:43
閱讀 1469·2021-11-18 10:02
閱讀 1942·2021-11-02 14:41
閱讀 2475·2019-08-30 15:55
閱讀 1125·2019-08-29 16:18
閱讀 2622·2019-08-29 14:15
閱讀 1446·2019-08-26 18:13
閱讀 830·2019-08-26 10:27