智能指針類模板(五十)
下來我們就來使用下 auto_ptr 智能指針
#include <iostream> #include <string> #include <memory> using namespace std; class Test { string m_name; public: Test(const char* name) { cout << "Hello, " << name << "!" << endl; m_name = name; } void print() { cout << "I'm " << m_name << "!" << endl; } ~Test() { cout << "Goodbye, " << m_name << "!" << endl; } }; int main() { auto_ptr<Test> pt(new Test("D.T.Software")); cout << "pt = " << pt.get() << endl; pt->print(); cout << endl; auto_ptr<Test> pt1(pt); cout << "pt = " << pt.get() << endl; cout << "pt1 = " << pt1.get() << endl; pt1->print(); return 0; }
我們定義了一個類 Test 用來說明問題。在 main 函數中先是用 auto_ptr 指針來創建了一個指向 Test 類的指針,經過下面這個指針 pt1 的操作後,pt 指針會指向空了。我們來看看編譯結果
我們看到在經過指針 pt1 指向 pt 操作之後,指針 pt 的值便為空了。而且我們也沒有 delete,它便會自動的去刪除指針,執行了析構函數。下來我們再來說說 STL 標準庫中的其它智能指針:a> shared_ptr,帶有引用計數機制,支持多個指針對象指向同一片內存;b> weak_ptr,配合 shared_ptr 而引入的一種智能指針;c> unique_ptr,一個指針對象指向一片內存空間,不能拷貝構造和賦值。
下來我們再來看看 QT 中的智能指針:a> QPointer,當其指向的對象被銷毀時,它會被自動置空,但是它析構時不會自動銷毀所指向的對象;b> QSharedPointer,引用計數型智能指針,可以被自由地拷貝和賦值,當引用計數為 0 時才刪除指向的對象。我們還是以 QT 中的代碼為例來進行分析(跟 C++ 差不多)
#include <QPointer> #include <QSharedPointer> #include <QDebug> class Test : public QObject { QString m_name; public: Test(const char* name) { qDebug() << "Hello, " << name << "!"; m_name = name; } void print() { qDebug() << "I'm " << m_name << "!"; } ~Test() { qDebug() << "Goodbye, " << m_name << "!"; } }; int main() { QPointer<Test> pt(new Test("D.T.Software")); QPointer<Test> pt1(pt); QPointer<Test> pt2(pt); pt->print(); pt1->print(); pt2->print(); delete pt; qDebug() << endl; qDebug() << "pt = " << pt; qDebug() << "pt1 = " << pt1; qDebug() << "pt2 = " << pt2; QSharedPointer<Test> spt(new Test("David")); QSharedPointer<Test> spt1(spt); QSharedPointer<Test> spt2(spt); spt->print(); spt1->print(); spt2->print(); return 0; }
在 QT 中的輸出是用 QDebug,它裏面的字符串是用 QString 表示。我們在 QPointer 類中是手動調用 delete 的,而在 QSharedPointer 並沒有去調用 delete。來看看編譯結果
我們看到已經實現了。在刪除了 QPointer 類後,它的三個指針都指向為空了。這便有效的防止了內存泄漏和野指針的操作了。那麽我們介紹了這麽多的智能指針後,我們再基於我們之前創建的智能指針,在它的基礎上自己再來實現一個智能指針類模板。
SmartPointer.h 源碼
#ifndef _SMARTPOINTER_H_ #define _SMARTPOINTER_H_ template < typename T > class SmartPointer { T* mp; public: SmartPointer(T* p = NULL) { mp = p; } SmartPointer(const SmartPointer<T>& obj) { mp = obj.mp; const_cast<SmartPointer<T>&>(obj).mp = NULL; } SmartPointer<T>& operator = (const SmartPointer<T>& obj) { if( this != &obj ) { delete mp; mp = obj.mp; const_cast<SmartPointer<T>&>(obj).mp = NULL; } return *this; } T* operator -> () { return mp; } T& operator * () { return *mp; } bool isNull() { return (mp == NULL); } T* get() { return mp; } ~SmartPointer() { delete mp; } }; #endif
test.cpp 源碼
#include <iostream> #include <string> #include "SmartPointer.h" using namespace std; class Test { string m_name; public: Test(const char* name) { cout << "Hello, " << name << "!" << endl; m_name = name; } void print() { cout << "I'm " << m_name << "!" << endl; } ~Test() { cout << "Goodbye, " << m_name << "!" << endl; } }; int main() { SmartPointer<Test> pt(new Test("D.T.Software")); cout << "pt = " << pt.get() << endl; pt->print(); cout << endl; SmartPointer<Test> pt1(pt); cout << "pt = " << pt.get() << endl; cout << "pt1 = " << pt1.get() << endl; pt1->print(); return 0; }
我們在 main 函數沒有改動,只是將 auto_ptr 指針改為我們自己實現的 SmartPointer 了,再來看看是不是和之前的效果是一樣的呢?
通過對智能指針類模板的學習,總結如下:1、智能指針是 C++ 中自動內存管理的主要手段;2、智能指針在各種平臺上都有不同的表現形式;3、智能指針能夠盡可能的避開內存相關的問題;4、STL 和 Qt 中都提供了對智能指針的支持。
歡迎大家一起來學習 C++ 語言,可以加我QQ:243343083。
智能指針類模板(五十)