初始化和賦值進行的轉換
這裏提到的三種潛在的數制轉換問題分別是
1.較大的浮點類型轉爲較小的浮點類型,會導致精度下降,比如double–>double,值可能超出目標類型的取值範圍,在這種情況下,結果將是不確定的
#include<iostream>
//#include<limits>
//#include<cfloat>
using namespace std;
int main()
{
double a = 10.0 / 3.0;
float b = 10.0 / 3.0;
const float million = 1.0e6;
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << a* million << endl;
cout << b* million << endl;
cout << a * million* million << endl;
return 0;
}
3333333.333333
3333333.250000
3333333333333.333496
可以在cfloat這個頭文件中看到,float的最小有效位數爲6位,
double爲15位,通過上面的例子可以看到,
float在第七位小數之後出現了錯誤,但是double直到第十五位之後纔出現錯誤
2.將浮點轉換爲整型,這種情況很常見,小數部分會丟棄
3.將較大的整形轉換爲較小的整形,比如long->short
以 {}方式進行轉換
這種方式不允許把精度高的轉換位精度低的
表達式中的轉換
這裏書上總結了很多,一共分爲兩類
- 自動轉化,在bool char unsigned char,signed char, short出現時,自動轉換爲int,這被稱爲整型提升
- 在不同類型的的變量進行運算時,也會進行轉化嗎,總結成一句話就是,把精度低的變量轉換成精度高的變量進行計算
強制轉換
之前我們常見的作法就是
(typeName) value 或者 typeName(value)
後來C++11 引入了四種強制類型轉換運算符,可以根據目的選擇一個適合的運算符,而不是使用通用的類型轉換。這隻出了進行類型轉換的原因,並讓編譯器能夠檢查程序的行爲是否與設計者想法相吻合
dynamic_cast
#include<iostream>
using namespace std;
class Low
{
public:
int a;
};
class High : public Low
{
public:
int b;
};
int main()
{
High* ph = new High;
Low* pl = dynamic_cast<Low *>(ph); //允許
Low* p2 = ph; //允許
Low* p3 = new High;
High *ph1 = p3; //編譯不允許,因爲子類指針不能直接指向父類空間
High* ph2 = (High *)p3; //強制轉換之後,編譯允許
High* ph3 = dynamic_cast<High*>(p3);//採用C++11 編譯不允許
return 0;
}
上面這種轉換,僅當Low是High的可訪問基類時,才能進行,那麼什麼是可訪問基類呢?
參考下面這個博客 https://www.cnblogs.com/zhaoyl/p/4966865.html
const_cast
這種轉換,只能改變值爲const 或者 volatile,關於const和* 可以參考我之前的博客
https://blog.csdn.net/qq_36437446/article/details/103099507在這裏的第四部分
如果有一個值,大多數時是常量,有時又是可以修改的,在這種情況下,可以將值聲明爲const,當需要修改的時候,使用這種轉換。
#include<iostream>
using namespace std;
class Low
{
public:
int a;
};
class High : public Low
{
public:
int b;
};
int main()
{
High bar;
bar.a = 10;
const High* pbar = &bar;
//pbar->a = 11; //這裏編譯時通不過的,因爲pbar指向一個const 的High型數據
High* pb = const_cast<High*>(pbar);
pb->a = 100;
//const Low* p1 = const_cast<const Low*>(pbar); //不允許,因爲嘗試修改變量類型從High *到Low *
return 0;
}
還有一點需要注意
#include<iostream>
using namespace std;
void change(const int*, int);
int main()
{
int pop1 = 100;
const int pop2 = 200;
cout << "pop1:" << pop1 << " pop2:" << pop2 << endl;
change(&pop1, -20);
change(&pop2, -20);
cout << "pop1:" << pop1 << " pop2:" << pop2 << endl;
return 0;
}
void change(const int* pt, int n)
{
int* pc;
pc = const_cast<int*>(pt);
*pc += n;
}
pop1:100 pop2:200
pop1:80 pop2:200
這裏爲什麼pop2的值沒有被修改呢,因爲雖然無法通過pt進行修改,因爲pt 的類型是指向const int型數據的指針,但是通過const_cast取消了pt的const屬性,所以pop1得以修改,但是因爲pop2這個值本身就是const,他是不可被修改的
這裏我理解的也不是太好,只是先記住了,以後相同了,再回來解釋
static_cast
還是上面的High 和 Low類
High bar;
Low blow;
High *pb = static_cast<High *>(&blow) //OK
Low * pl = static_cast<Low *>(&bar) //ok
如果這裏有一個獨立的類A
A * a = static_cast<A *>(&bar) //不允許
reinterpret_cast
這種轉換適用於依賴於實現的底層編程技術,目前我還沒有遇到股,這裏不進行介紹