一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - 關于C++的強制類型轉換淺析

關于C++的強制類型轉換淺析

2021-06-01 15:14Dawn_sf C/C++

C++的強制類型轉換是我們在日常開發中經常會遇到的,下面這篇文章主要給大家介紹了關于C++強制類型轉換的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。

前言

一說起強制類型轉換大家都很熟悉,相信很多學習完C++的朋友還在使用C語言的強制類型的方式 (類型)變量.

C++其實也具有自己的一套強制類型轉換它們分明是:static_cast  reinterpret_cast  const_cast  dynamic_cast四種類型.

那么肯定會有人好奇C++是不是閑,C語言的強制類型用的舒舒服服的,為什么要新推出來這幾個?

新類型的強制轉換可以提供更好的控制強制轉換過程,允許控制各種不同種類的強制轉換。C++中風格是static_cast<type>。C++風格的強制轉換其他的好處是,它們能更清晰的表明它們要干什么。程序員只要掃一眼這樣的代碼,就能立即知道一個強制轉換的目

的。

static_cast                                                                                              

static_cast用于非多態類型的轉換(靜態轉換),任何標準轉換都可以用它,但它不能用于兩個不相關的類型進行轉換.

何為不相關類型? 比如int 和 double char short就是相關類型. 和int*就是不相關類型.

我們來看一看static_cast的用法.  例如,通過將一個運算對象強制轉換成double類型就能使表達式執行浮點數除法:

?
1
double slope = static_cast<double>(j) / i;

當static_cast需要把一個較大的算術類型賦值給較小的類型時,static_cast非常有用。此時,強制類型轉換告訴程序的讀者和編譯器:我們知道并且不在乎潛在的精度損失。一般來說,如果編譯器發現一個的算術類型試圖賦值給較小的類型,就會給出警告信息;但是當我們執行了顯式的類型轉換后,警告信息就會被關閉了。

reinterpret_cast                                                                                        

reinterpret_cast有著和C風格的強制轉換同樣的能力。它可以轉化任何內置的數據類型為其他任何的數據類型,也可以轉化任何指針類型為其他的類型。它甚至可以轉化內置的數據類型為指針,無須考慮類型安全或者常量的情形。不到萬不得已絕對用。

因為reinterpret_cast是一個蠻bug的操作,下面我來演示一下.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef void (* FUNC)();
int DoSomething (int i)
{
  cout<<"DoSomething" <<endl;
  return 0;
}
void Test ()
{
  // reinterpret_cast可以編譯器以FUNC的定義方式去看待 DoSomething函數
  // 所以非常的BUG,下面轉換函數指針的代碼是不可移植的,所以不建議這樣用
  // C++不保證所有的函數指針都被一樣的使用,所以這樣用有時會產生不確定的結果
  FUNC f = reinterpret_cast< FUNC>(DoSomething );
  f();
}

當你這樣運行的時候,你會發現通過函數指針沒有傳參數調用這個有參數的函數居然可以調用,這就很尷尬了,所以我告訴你不到萬不得已就不要使用reinterpret_cast

const_cast

對于將常量對象轉化為非常量對象的行為,我們一般稱之為“去掉const性質”。一旦我們去掉了某個對象的const性質,編譯器就不再阻止我們對該對象進行寫操作了。如果對象本身不是一個常量,使用強制類型轉換獲得寫權限是合法的行為。然而如果對象是一個常量,再使用const_cast執行寫操作就會產生未定義的后果。

舉個例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
#include<Windows.h>
#include<assert.h>
 
using namespace std;
 
int main()
{
 const int a = 2;
 int *p = const_cast<int*>(&a);
 *p = 3;
 cout << a << endl;
 system("pause");
 return 0;
}

我們有理由的認為在內存當中a的值被修改為3,但是結果呢? 我們來看一看

關于C++的強制類型轉換淺析

這不科學啊?? 我們再打開監視窗口看一下a的值.

關于C++的強制類型轉換淺析

我們都知道監視窗口看到的都是從內存當中拿到的,但是為什么內存當中為3,打印出來就是2呢? 我來解釋一下.

C++編譯器具有優化功能,當你定一個const的常量的時候,系統覺得它不會被改變了,于是做一個優化把該常量存到寄存器當中,下次訪問的過程更快速一點. 所以當顯示窗口讀取數據的時候,他會直接去寄存器當中讀取數據.而不是去內存,所以導致我們明明該掉了a的值,卻打印不出來,但是如何解決這個問題呢??

c++有一個關鍵字: volatile 該關鍵字的作用防止編譯器優化,這個時候要輸出a就會老老實實的回內存去查看.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
#include<Windows.h>
#include<assert.h>
 
using namespace std;
 
int main()
{
 volatile const int a = 2;
 int *p = const_cast<int*>(&a);
 *p = 3;
 cout << a << endl;
 system("pause");
 return 0;
}

dynamic_cast                                                                                           

前三種的強制類型轉換,他們能做到的C語言的強制類型轉換也大多能做到,最后一種C語言的強制類型轉換就沒有辦法了.

在類的轉換時,在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的。在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。當用于多態類型時,它允許任意的隱式類型轉換以及相反過程. 不過,與static_cast不同,在后一種情況里(注:即隱式轉換的相反過程),dynamic_cast 會檢查操作是否有效. 也就是說, 它會檢查轉換是否會返回一個被請求的有效的完整對象。檢測在運行時進行. 如果被轉換的指針不是一個被請求的有效完整的對象指針,返回值為NULL. 對于引用 類型,會拋出bad_cast異常

你說這個強轉有啥用,其實對于我這種菜鳥還真的沒用過,不過我知道一個問題可以使用這樣的方法解決. 給你兩個類讓你分辨那個是子類那個是父類,我們來看看是如何解決的.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<iostream>
#include<Windows.h>
#include<assert.h>
 
using namespace std;
 
class AA
{
public:
 
 virtual void fun1()
 {
  cout << "hehe" << endl;
 }
public:
 int a;
};
 
class BB :public AA
{
public:
 
 virtual void fun1()
 {
  cout << "heh2e" << endl;
 }
public:
 int c;
};
int main()
{
 AA* q = new AA();
 BB* p = new BB();
 AA* a;
 BB* b;
 
 b = dynamic_cast<BB*>(q);
 if (b == NULL)
 {
  cout << "AA為基類" << endl;
 }
 else{
  cout << "AA為子類" << endl;
 }
 
 a = dynamic_cast<AA*>(p);
 if (a == NULL)
 {
  cout << "BB為基類" << endl;
 }
 else
 {
  cout << "BB為子類" << endl;
 }
 system("pause");
 return 0;
}

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://blog.csdn.net/dawn_sf/article/details/77914861

延伸 · 閱讀

精彩推薦
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
主站蜘蛛池模板: 亚洲精品乱码蜜桃久久久 | 亚洲国产精品日韩高清秒播 | www.羞羞答答 | free性泰国娇小videos | 欧美午夜网站 | 美国雪白人妖sarina | 免费在线中文字幕 | 国产成人夜色影视视频 | 亚洲欧美在线免费 | 男人狂躁女人下面的视频免费 | 女海盗斯蒂内塔的复仇2免费观看 | 五月天中文在线 | 成人精品视频一区二区在线 | 99草视频 | 波多野结衣快播 | 99热er | 大桥未久一区二区 | 男人女人插 | 洗濯屋H纯肉动漫在线观看 武侠艳妇屈辱的张开双腿 午夜在线观看免费观看 视频 | 国内精品久久久久久野外 | 唯美 清纯 另类 亚洲制服 | 好吊妞视频998www | 激情男人天堂 | 免费二级毛片免费完整视频 | 小草视频免费观看在线 | 青青视频国产依人在线 | 亚洲无线一二三四区 | 国产成人精品一区二区仙踪林 | 拿捏小说| 精品欧美一区二区三区四区 | 精品国产欧美一区二区 | 91精品国产高清久久久久久91 | 亚洲AV永久无码精品澳门 | 日本ccc三级 | 国产90后美女露脸在线观看 | 青草视频久久 | 色吊丝每日永久访问网站 | 午夜久久久久久网站 | 亚洲精品国产自在现线最新 | julianann办公室 | 久草在线精彩免费视频 |