最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++四種cast使用詳細介紹

 更新時間:2022年07月26日 15:48:24   作者:三貝勒文子  
本文主要介紹了C++四種cast使用詳細介紹,今天我們要來講的是顯式類型轉(zhuǎn)換,C++提供了四種顯式類型轉(zhuǎn)換,分別是:static_cast、dynamic_cast、const_cast、reinterpret_cast,感興趣的可以了解一下

在C++中,我們經(jīng)常使用到類型的轉(zhuǎn)換,像把一個int類型轉(zhuǎn)換成char類型,一個int類型轉(zhuǎn)換成double類型,這些轉(zhuǎn)換屬于隱式類型轉(zhuǎn)換。而今天我們要來講的是顯式類型轉(zhuǎn)換。C++提供了四種顯式類型轉(zhuǎn)換,分別是:static_cast、dynamic_cast、const_cast、reinterpret_cast

一、static_cast

static_cast的定義為:

static_cast<type_name>(expression)

type_name是轉(zhuǎn)換的類型,expression是被轉(zhuǎn)換的對象或者表達式。

static_cast一般用于隱式轉(zhuǎn)換,當type_name和express至少有一方可以隱式轉(zhuǎn)換時,則可以用static進行強制類型轉(zhuǎn)換??梢杂糜诔R姷膇nt、float、double等類型轉(zhuǎn)換;轉(zhuǎn)換成功返回true,否則返回false(相當于C語言中的強制類型轉(zhuǎn)換)。

1、基本數(shù)據(jù)類型轉(zhuǎn)換

double serven_double_1 = 1.2;
std::cout<<serven_double_1<<std::endl;
 
int serven_int_1 = static_cast<int>(serven_double_1);
std::cout<<serven_int_1<<std::endl;
 
double serven_double_2 = static_cast<double>(serven_int_1);
std::cout<<serven_double_2<<std::endl;

運行結(jié)果:基本類型的轉(zhuǎn)換,可以看到double類型轉(zhuǎn)換成int類型后丟失了精度,這一點跟reinterpret_cast不一樣,reinterpret_cast是底層二進制的強制拷貝和語義轉(zhuǎn)換,所以不會丟失精度,后面會講到。

2、指針和void指針的轉(zhuǎn)換

int* serven_int_2 = new int(2);
void * serven_void_1 = static_cast<void*>(serven_int_2);
int *serven_int_3 = static_cast<int*>(serven_void_1);
*serven_int_2 = 6;
 
std::cout<<*serven_int_2<<std::endl;
std::cout<<*serven_int_3<<std::endl;
std::cout<<serven_void_1<<std::endl;
std::cout<<serven_int_2<<std::endl;
std::cout<<serven_int_3<<std::endl;

 運行結(jié)果:void指針和其他類型的指針進行轉(zhuǎn)化的時候,他們都是指向同一個地址。

 3、父類和子類之間的轉(zhuǎn)換

class SERVEN_PARENT{
public:
    SERVEN_PARENT(){}
    void Function(){
        std::cout<<"PARENT"<<std::endl;
    }
};
 
class SERVEN_CHILD : public SERVEN_PARENT{
public:
    SERVEN_CHILD(){}
    void Function(){
        std::cout<<"CHILD"<<std::endl;
    }
};
 
 
void main(){
 
    SERVEN_PARENT* ser_par = new SERVEN_PARENT();
    ser_par->Function();
    SERVEN_CHILD* ser_chi = static_cast<SERVEN_CHILD*>(ser_par);
    ser_chi->Function();
 
}

運行結(jié)果:在main函數(shù)第二行中定義了一個ser_chi,是一個派生類對象,然后強制將基類對象轉(zhuǎn)換成子類,這種叫做下行轉(zhuǎn)換,轉(zhuǎn)換后打印的結(jié)果是子類的Function,使用static_cast來進行向下轉(zhuǎn)換是不安全的,因為當子類中定義了基類沒有的變量,并且在Function函數(shù)中使用了這個變量,那么程序?qū)箦e。

 下面我們來看一下static_cast不安全的例子:

class SERVEN_PARENT{
public:
    SERVEN_PARENT(){}
    void Function(){
        std::cout<<"PARENT"<<std::endl;
    }
};
 
class SERVEN_CHILD : public SERVEN_PARENT{
public:
    SERVEN_CHILD(){}
    void Function(){
        std::cout<<"CHILD"<<std::endl;
        std::cout<<nums<<std::endl;
    }
 
private:
    char nums = 'g';
};
 
 
void main(){
 
    SERVEN_PARENT* ser_par = new SERVEN_PARENT();
    ser_par->Function();
    SERVEN_CHILD* ser_chi = static_cast<SERVEN_CHILD*>(ser_par);
    ser_chi->Function();
 
}

 運行結(jié)果:因為派生類對象使用了自己獨有的變量,所以打印char字符的時候就出現(xiàn)了亂碼。

二、dynamic_cast

dynamic_cast的定義為:

dynamic_cast<type_name>(expression)

type_name是轉(zhuǎn)換的類型,expression是被轉(zhuǎn)換的對象或者表達式。

dynamic一般用于基類指向派生類時的強制轉(zhuǎn)換,轉(zhuǎn)換成功返回true,失敗返回false。它不像static_cast一樣向下轉(zhuǎn)換不安全,它是安全的。它的安全性體現(xiàn)在RTTI,那什么是RTTI呢?
RTTI是運行時類型識別。程序能夠使用基類的指針或引用來檢查著這些指針或引用所指的對象的實際派生類型(判斷指針原型)。RTTI提供了兩個非常有用的操作符:typeid和dynamic_cast。(三個最主要的東西,dynamic_cast,typeid,type_info)。typeid:typeid函數(shù)(為type_info類的友元函數(shù),為什么要這樣呢?目的是防止創(chuàng)建type_info對象)的主要作用就是讓用戶知道當前的變量是什么類型的,它可以返回一個type_info的引用,可以獲取類的名稱和編碼typeid重載了type_info中的==和!=可以用于判斷兩個類型是否相等。
dynamic_cast和static_cast在類繼承的區(qū)別就是dynamic_cast向下轉(zhuǎn)換是安全的。

三、const_cast

const_cast的定義為:

const_cast<type_name>(expression)

type_name是轉(zhuǎn)換的類型,expression是被轉(zhuǎn)換的對象或者表達式。

const_case有兩個功能,分別是去掉const和加上const,一般用于去掉const,修改被const修飾為常量的值。但是修改的這個值本身不能是const常量,而是被二次引用或者傳參數(shù)時被引用為const,才能修改,否則修改失敗。同時type和express兩個類型要一直去掉const,修改成功返回true,否則返回false。

1、加上const

int* serven_int_4 = new int(2);
const int* serven_int_5 = const_cast<const int*>(serven_int_4);     // 轉(zhuǎn)換為常量指針
*serven_int_4 = 3;
//*serven_int_5 = 4;              // 不能修改
std::cout<<*serven_int_4<<std::endl;
std::cout<<*serven_int_5<<std::endl;
std::cout<<serven_int_4<<std::endl;
std::cout<<serven_int_5<<std::endl;

2、去掉const

(1)const修飾指針,指針指向一個類對象(常量指針)

將一個常量指針轉(zhuǎn)換成非常量指針。

class SERVEN_PARENT{
public:
    SERVEN_PARENT(){}
    void Function(){
        std::cout<<"PARENT"<<std::endl;
    }
};
 
class SERVEN_CHILD : public SERVEN_PARENT{
public:
    SERVEN_CHILD(){}
    void Function(){
        std::cout<<"CHILD"<<std::endl;
        std::cout<<nums<<std::endl;
    }
 
private:
    char nums = 'g';
};
 
void main(){
    SERVEN_PARENT ser_par;
    const SERVEN_PARENT* pP = &ser_par;
    SERVEN_PARENT* pP_1 = const_case<SERVEN_PARENT*>(pP);    // 強制將pP轉(zhuǎn)換成非const
    
}

(2)const修飾指針指向?qū)ο蟮臄?shù)值(指針常量)

將指針常量轉(zhuǎn)換為非指針常量。

void main(){
    SERVEN_PARENT ser_par;
    SERVEN_PARENT* const pP = &ser_par;
    SERVEN_PARENT* pP_1 = const_case<SERVEN_PARENT*>(pP);    // 強制將pP轉(zhuǎn)換成非const
    
}

(3)const修飾指針指向?qū)ο蟮臄?shù)值并且修飾指針(常量指針常量)

常量指針常量可以被轉(zhuǎn)換為非常量指針常量,也可以轉(zhuǎn)換成指針常量或者常量指針。

void main(){
    SERVEN_PARENT ser_par;
    const SERVEN_PARENT* const pP = &ser_par;
    SERVEN_PARENT* pP_1 = const_cast<SERVEN_PARENT*>(pP);    // 強制將pP轉(zhuǎn)換成非const
    const SERVEN_PARENT* pP_2 = const_cast<SERVEN_PARENT*>(pP);    // 強制將pP轉(zhuǎn)換成常量指針
    SERVEN_PARENT* const pP_2 = const_cast<SERVEN_PARENT*>(pP);    // 強制將pP轉(zhuǎn)換成指針常量
 
    
}

四、reinterpret_cast

reinterpret_cast的定義為:

reinterpret_cast<type_name>(expression)

type_name是轉(zhuǎn)換的類型,expression是被轉(zhuǎn)換的對象或者表達式。

reinterpret_cast是一種比較粗暴的轉(zhuǎn)換方式,并且是最不安全的,為什么說它粗暴呢?因為它直接去拷貝最底層的二進制,它的本質(zhì)是編譯器的指令,它的作用是可以把一個指針轉(zhuǎn)換成一個整數(shù),也可以把一個整數(shù)轉(zhuǎn)換成一個指針?;蛘卟煌愋偷闹羔樝嗷マD(zhuǎn)換。

double serven_double_2 = 1.20;
char* serven_char_1 = reinterpret_cast<char* >(&serven_double_2);
double* serven_double_3 = reinterpret_cast<double*>(serven_char_1);
std::cout<<*serven_double_3<<std::endl;
 
int* serven_int_6 = reinterpret_cast<int*>(&serven_double_2);
double* serven_double_4 = reinterpret_cast<double*>(serven_int_6);
std::cout<<*serven_double_3<<std::endl;

運行結(jié)果:我們可以看到reinterpret_cast將double類型轉(zhuǎn)換成int,再轉(zhuǎn)換成double類型后精度不會丟失,而static_cast會丟失。

到此這篇關于C++四種cast使用詳細介紹的文章就介紹到這了,更多相關C++ cast使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++實現(xiàn)中綴轉(zhuǎn)后綴的示例詳解

    C++實現(xiàn)中綴轉(zhuǎn)后綴的示例詳解

    這篇文章主要為大家詳細介紹了如何利用C++實現(xiàn)中綴轉(zhuǎn)后綴的問題,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 深入理解C++中std::chrono庫的使用

    深入理解C++中std::chrono庫的使用

    在程序設計中,時間管理是一個核心概念,它不僅關系到程序的效率和性能,而且直接影響用戶體驗,C++作為一門高效的編程語言,提供了std::chrono庫,用于精確地處理和計算時間,下面就跟隨小編一起學習一下std::chrono庫的使用吧
    2023-12-12
  • C++ Virtual關鍵字的具體使用

    C++ Virtual關鍵字的具體使用

    這篇文章主要介紹了C++ Virtual關鍵字的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 基于C語言實現(xiàn)簡易掃雷游戲

    基于C語言實現(xiàn)簡易掃雷游戲

    這篇文章主要為大家詳細介紹了基于C語言實現(xiàn)簡易掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下<BR>
    2022-01-01
  • C++中String類常見題目分享

    C++中String類常見題目分享

    這篇文章主要為大家詳細介紹了一些C++中String類的常見題目,文中的示例代碼講解詳細,對我們掌握C++有一定的幫助,感興趣的小伙伴可以了解一下
    2023-06-06
  • OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單)

    OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單)

    這篇文章主要介紹了OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • C++實例分析組合數(shù)的計算與排列組合的產(chǎn)生

    C++實例分析組合數(shù)的計算與排列組合的產(chǎn)生

    這篇文章主要介紹了C++組合數(shù)的計算與排列和組合無重集元素的產(chǎn)生,對計算算法感興趣的同學,可以參考一下,理解其原理,并且試驗一下。
    2022-07-07
  • 詳解C++實現(xiàn)鏈表的排序算法

    詳解C++實現(xiàn)鏈表的排序算法

    鏈表排序思想和數(shù)組排序類似,區(qū)別就是數(shù)組遍歷容易,數(shù)據(jù)交換也容易;鏈表(單項鏈表)只能一個方向遍歷,不能逆序遍歷,且不能隨機訪問,所以排序比較麻煩。本文將詳細介紹鏈表排序的方式,并且用C++來實現(xiàn)
    2021-06-06
  • C語言 常量,變量及數(shù)據(jù)詳細介紹

    C語言 常量,變量及數(shù)據(jù)詳細介紹

    這篇文章主要介紹了C語言 常量,變量及數(shù)據(jù)詳解的相關資料,需要的朋友可以參考下
    2016-10-10
  • C++和C的混合編譯的項目實踐

    C++和C的混合編譯的項目實踐

    本文主要介紹了C++和C的混合編譯的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06

最新評論

乌恰县| 穆棱市| 丽水市| 淮安市| 宣恩县| 应城市| 嘉兴市| 当涂县| 工布江达县| 湖州市| 丹棱县| 衡南县| 廊坊市| 合川市| 繁峙县| 井冈山市| 怀化市| 轮台县| 南昌市| 潮州市| 伊宁市| 河津市| 溆浦县| 渝北区| 措勤县| 深州市| 北宁市| 阜新市| 二连浩特市| 抚州市| 鹿邑县| 筠连县| 南宁市| 黄石市| 霍邱县| 娄烦县| 峨边| 革吉县| 柳江县| 垦利县| 龙南县|