C 之型別轉化和智慧型指標

2021-10-21 02:17:28 字數 3955 閱讀 6269

目錄

一、型別轉化和智慧型指標

二、型別轉化

1. static_cast

2. dynamic_cast

3. const_cast

4. reinterpret_cast

二、智慧型指標

1. shared_ptr

2. unique_ptr

3. wake_ptr

4. 注意事項 總結

強制型別轉化和智慧型指標相關, c++對型別轉換做了細分,提供了四種不同型別轉換,以支援不同需求的轉換, 型轉換有了統一的標示符,利於**排查和檢視。智慧型指標最為方便的就是能自動管理堆記憶體,無需關心何時收回已分配的記憶體。

該轉換用於將一種資料型別強制轉換為另一種資料型別。在進行資料傳遞時轉void*,即可以使用static_cast找回存在於void*指標中的值。

algo_result.reserved = static_cast(logname);

char* algo_name = static_cast(algo_result.reserved);

a: 用於基類和派生類之間指標或引用的轉換

進行上行轉換(把派生類的指標或引用轉換成基類表示)是安全的

進行下行轉換(把基類的指標或引用轉換為派生類表示),由於沒有動態型別檢查,所以是不安全的

b: 用於基本資料型別之間的轉換,如把int轉換成char。

c: 把任何型別的表示式轉換為void型別

a: 執行時處理的,執行時要進行型別檢查。

b: 不能用於內建的基本資料型別的強制轉換。

c: 轉換如果成功的話返回的是指向類的指標或引用,轉換失敗的話則會返回null。

d: 使用dynamic_cast進行轉換的,基類中一定要有虛函式,否則編譯不通過。

class base

public:

int _b;

};class derived:public base

;int main(void)

在基類派生類互相轉換時,雖然static_cast是在編譯期完成,效率更高,但是不安全,上例中就示範了乙個踩記憶體的例子。相比之下因為dynamic_cast可以檢視執行時資訊,上例如果base含有虛函式,那麼drvptrb就是乙個空指標不能操作derived中_d的資料從而保證安全性,所以應該優先使用dynamic_cast。

用於強制去掉不能被修改的常數特性,但需要特別注意的是const_cast不是用於去除變數的常量性,而是去除指向常數物件的指標或引用的常量性,其去除常量性的物件必須為指標或引用。

a: 常量指標轉換為非常量指標,並且仍然指向原來的物件

b: 常量引用被轉換為非常量引用,並且仍然指向原來的物件

c: cosnt_cast是四種型別轉換符中唯一可以對常量進行操作的轉換符

const double a = 11;

const double* p = &a;

double* q = const_cast(p);

在使用reinterpret_cast強制轉換過程僅僅只是位元位的拷貝,因此在使用過程中需要特別謹慎

class basea

int _c;

};class baseb

int _d;

};int main(void)

; std::shared_ptrson;

std::cout << "dad owns " << (dad ? *dad : "nothing") << std::endl;

std::cout << "son owns " << (son ? *son : "nothing") << std::endl;

std::cout << std::endl;

son = dad;

std::cout << "dad owns " << (dad ? *dad : "nothing") << std::endl;

std::cout << "son owns " << (son ? *son : "nothing") << std::endl;

std::cout << std::endl;

dad = nullptr;

std::cout << "dad owns " << (dad ? *dad : "nothing") << std::endl;

std::cout << "son owns " << (son ? *son : "nothing") << endl;

}

dad owns ps4

son owns nothing

dad owns ps4

son owns ps4

dad owns nothing

son owns ps4

對資源獨占性的智慧型指標,乙個物件資源只能被乙個ptr指向。dad物件是指向sonunique_ptr,如果要dad放棄對這個物件的所有權,就需要呼叫dad.release()來將所有權進行釋放,這個函式將會返回指向son的普通指標son*,現在就可以用這個不屬於任何人的普通指標來構造乙個新的unique_ptr

int main() ;

std::cout << "dad owns " << (dad ? *dad : "nothing") << std::endl;

std::unique_ptroldwang;

std::cout << "dad owns " << (dad ? *dad : "nothing") << std::endl;

std::cout << "oldwang owns " << (oldwang ? *oldwang : "nothing") << std::endl;

}

從shared_ptr構造乙個weak_ptr,也就是說有weak_ptr就肯定有shared_ptr,如果要使用weak_ptr所指向的物件,我們需要呼叫lock()函式,這個函式會返回所指物件的shared_ptr。

shared_ptraccountowner;

weak_ptraccountthief;

cout << "accountowner owns "

<< (accountowner ? *accountowner : "nothing") << endl;

cout << "accountthief can use "

<< (!accountthief.expired() ? *accountthief.lock() : "nothing") << endl;

cout << endl;

accountowner = nullptr;

cout << "accountowner owns "

<< (accountowner ? *accountowner : "nothing") << endl;

cout << "accountthief can use "

<< (!accountthief.expired() ? *accountthief.lock() : "nothing") << endl;

我們不能把並不指向堆記憶體的指標賦值給智慧型指標,如delete乙個指向棧記憶體的指標。

乙個物件的智慧型指標通過某種路徑的一連串智慧型指標最終指向了自身,最終構成了乙個環,這個物件就永遠不會被自動釋放了,這就是智慧型指標會造成的記憶體洩漏。

class foo ;

int main() ;

shared_ptrb;

a->father = b;

b->father = a;

}

型別轉化和智慧型指標**好用

c 智慧型指標

auto prt 它是 它所指向物件的擁有者 所以當自身物件被摧毀時候,該物件也將遭受摧毀,要求乙個物件只有乙個擁有者,注意 auto prt 不能使用new 來分配物件給他 include include using namespace std template void bad print au...

c 智慧型指標

很久沒寫部落格了,不知道如何表達了,哈哈.我先介紹一下深淺拷貝.class copy 此時a.ptr和b.ptr指向同乙個物件,當我們delete a.ptr時 b.ptr所指向的物件已經不存在了,要是我們引用b.ptr指向的物件也就會出問題了.深拷貝 把a.ptr所指向的物件拷貝乙份給b.ptr ...

c 智慧型指標

記得前不久有一次面試被問到智慧型指標的實現,當時對智慧型指標只是聽說但沒有了解過,就亂七八糟地說了一遍。今天寫了一遍智慧型指標,用了引用計數的概念。主要思想就是,用乙個新類對原本需要的型別進行了一層封裝,這個新類中儲存了原本的物件指標和乙個引用計數的指標,之所以全部用指標來儲存,就是因為會出現多個新...