C 智慧型指標!

2021-09-16 13:38:18 字數 2294 閱讀 9252

1、了解智慧型指標之前,我們先了解什麼是裸指標?

凡是帶*的都是裸指標,也就是我們c和c++中一直接觸的指標。但是指標雖然好用,但是當它在堆上開闢記憶體之後,如果使用之後處理不當都會引起一系列的問題。比如:

(1)如果得不到及時的手動釋放,會造成記憶體洩漏。

(2)多次釋放同一塊資源,產生野指標,甚至有可能導致程式崩潰。

(3)寫了釋放資源的語句,但卻從之前return出去了。

但在c++ 11中有了乙個新的概念「智慧型指標」

2、什麼是智慧型指標?

智慧型指標是儲存指向動態分配(堆)物件指標的類,把乙個計數器與類指向的物件相關聯,引用計數跟蹤該類有多少個物件的指標指向同乙個物件

而智慧型指標的智慧型體現在無論如何,保證資源一定會釋放。智慧型指標並不是乙個指標,而是乙個模板。由智慧型指標這個模板例項化出來的類的物件具有和裸指標相似的行為,但是它能夠自動的釋放所指向的物件,所以我們稱之為智慧型指標。如果我們用普通指標來建立乙個指向某個物件的指標,那麼我們最後必須要手動釋放這塊空間,而智慧型指標它是乙個例項化出來的物件,它釋放空間是通過自己類內的析構函式完成的。

智慧型指標原理:利用棧上的物件出作用域自動析構的特點,把資源釋放的**,放在智慧型指標的析構函式裡面。智慧型指標實際上是乙個棧物件,並非指標型別,在棧物件生命期即將結束時,智慧型指標通過析構函式釋放由它管理的堆記憶體。

1、我們以前使用裸指標的情況:

int main()

2、簡單智慧型指標實現:

可以看到建立的ptr物件先呼叫了建構函式然後呼叫了析構函式。因為ptr是棧上的智慧型指標物件,在建構函式中初始化資源,不管是函式正常執行完,還是執行過程**現異常,該物件都會自動呼叫析構函式,在析構函式中進行了delete操作,釋放資源。

所以我們可以了解到智慧型指標物件可以在棧上定義,那麼可不可以在堆上定義智慧型指標呢?

csmartptr*ptr2 = new csmartptr(new int);
從**中我們可以看到定義ptr2物件時出現了*,所以看起來它好像是定義了乙個智慧型指標,但實際上還是乙個裸指標,需要我們進行手動釋放資源。所以說是不可以在堆上定義智慧型指標的。

3、為智慧型指標提供過載函式

前面我們已經說過了,智慧型指標不是指標,而是為了彌補指標有可能帶來的不足,對程式造成的困擾而封裝的乙個類。所以其實它就是在模仿指標的功能,但同時又彌補了不足。但在c++中,我們為了使智慧型指標用起來與裸指標一樣。所以我們必須提供*和->運算子的過載函式來完善其功能。

提供過載函式之後,我們就可以通過 * 來得到指標所對應的值,這時的使用就和裸指標基本一樣了。但是它也有存在的問題。

int main()

如果我們用已初始化的智慧型指標ptr1來初始化ptr2,程式執行之後會崩潰掉。為什麼呢?因為程式的預設拷貝建構函式做的是淺拷貝。所以用ptr2來初始化ptr1時,兩個智慧型指標是指向同一塊記憶體的。程式結束之後,ptr2先被析構,此時ptr2和ptr1指向的同一塊記憶體已經被析構過一次。但是程式結束的時候ptr1也是要被析構的,所以造成程式崩潰。

針對上面這個問題,要解決智慧型指標的兩大問題:

(1)怎麼解決智慧型指標的淺拷貝問題?

(2)怎麼使得多個智慧型指標指向同一塊資源時,而只被釋放一次資源?

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 智慧型指標

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