C/C++——跟我重寫智慧指標auto_ptr模版類
第一次使用auto_ptr的時候感覺很好用,但是對內部原理根本不懂,心裡不知道這東西到底是個什麼東東,總是感覺這東東比較陌生。今天有時間來簡單實現一下該類模版auto_ptr,實現了該模版類的主要功能,可以讓大家瞭解一下這個東東內部到底是個什麼情況。
棧物件和堆物件的區別:
首先,看一下兩種類物件的區別,一個是在棧上分配空間,另一個是在堆上分配空間。
如果看到這裡,你不清楚堆和棧的區別。那我也不解釋了,自行Google..(如果你想baidu也不攔你)
1、先測試棧上分配的物件
#include <iostream>
#include <memory>
using namespace std;
/****************************************
* 類名稱:A(用於測試的類)
****************************************/
class A
{
public:
A(int num):a(num){cout << "A(int num)" << endl;}
A(){cout << "A()" << endl;}
~A(){cout << "~A()" << endl;}
void func(){
cout << "A.fun()" << endl;
}
private:
int a;
};
/****************************************
* 主測試函式main
****************************************/
int main()
{
A a1;
a1.func();
//A * pa = new A();
//pa->func();
return 0;
}
程式輸出為:
A()
A.fun()
~A()
從輸出結果可以看出,在棧上分配的物件在離開作用域的時候會自動呼叫解構函式,不用手動釋放。
2、再測試堆上分配的物件
將上面的main函式改為下面:
/****************************************
* 主測試函式main
****************************************/
int main()
{
//A a1;
//a1.func();
A * pa = new A();
pa->func();
return 0;
}
程式輸出為:
A()
A.fun()
從輸出結果可以看出,在堆上分配的物件在離開作用域的時候不會自動呼叫解構函式,需要手動釋放。
下面是新增手動釋放物件的語句:
/****************************************
* 主測試函式main
****************************************/
int main()
{
//A a1;
//a1.func();
A * pa = new A();
pa->func();
delete pa;
return 0;
}
下面是改了之後的程式輸出:
A()
A.fun()
~A()
為什麼需要智慧指標?
從上面的例子可以看出,對於在堆上分配的物件的釋放是一件比較麻煩的事情,如果忘了手動釋放,那就會造成記憶體的洩漏。如果全部收到釋放,那麼又給程式設計師帶來很大的麻煩。
那麼就想啊,有什麼辦法可以像棧物件那樣操作堆物件。棧物件是在棧記憶體空間的物件,當物件超過作用域的時候會自動釋放。那麼我們可以讓棧記憶體空間上的一個指標物件專門來管理堆物件,當指標物件離開作用域的時候肯定會呼叫自身的解構函式,那麼我們在指標物件的解構函式中對它管理的堆物件記憶體空間進行釋放。
智慧指標auto_ptr簡單應用例項:
#include <iostream>
#include <memory>
using namespace std;
/****************************************
* 類名稱:A(用於測試的類)
****************************************/
class A
{
public:
A(int num):a(num){cout << "A(int num)" << endl;}
A(){cout << "A()" << endl;}
~A(){cout << "~A()" << endl;}
void func(){
cout << "A.fun()" << endl;
}
private:
int a;
};
/****************************************
* 主測試函式main
****************************************/
int main()
{
//使用智慧指標模版類auto_ptr
//new A等價於new A(),但是如果有括號的話,可以呼叫帶參的建構函式,如new A(10);
auto_ptr<A> ptr(new A);
ptr->func();
(*ptr).func();
return 0;
}
程式輸出為:
A()
A.fun()
A.fun()
~A()
在上面的例子中可以看出,auto_ptr是一個模版類,我們在這裡定義了一個管理類A物件的一個指標物件ptr,該指標物件ptr可以使用運算子->和*,所以在類auto_ptr中過載了運算子->和*。
在上面例子中的指標物件ptr是棧物件,在離開作用域的時候會自動釋放,然後會自動呼叫解構函式,在它的解構函式中會釋放它指向的堆物件,從而達到了智慧指標的效果。
重寫智慧指標模版類SmartPointer:
/****************************************
* 類名稱:Smart智慧指標模版類
****************************************/
template<typename T>
class SmartPointer
{
public:
//建構函式
SmartPointer(T * p = NULL):ptr(p){
}
//解構函式
~SmartPointer(){
if(ptr != NULL)
delete ptr;
}
//過載->運算子
T * operator->(){
return ptr;
}
//過載*運算子
T & operator*(){
return *ptr;
}
private:
T * ptr;
};
在程式中可以看出,該模版類過載了運算子->和*,並實現了管理堆物件的功能。
下面是測試智慧指標模版類SmartPointer:
/*************************************************************************
> File Name: smartPointerTemplate.cpp
> Author:
> Mail:
> Created Time: 2016年05月10日 星期二 19時26分14秒
************************************************************************/
#include <iostream>
using namespace std;
/****************************************
* 類名稱:A(用於測試的類)
****************************************/
class A
{
public:
A(int num):a(num){cout << "A(int num)" << endl;}
A(){cout << "A()" << endl;}
~A(){cout << "~A()" << endl;}
void func(){
cout << "A::fun()" << endl;
}
private:
int a;
};
/****************************************
* 類名稱:B(用於測試的類)
****************************************/
class B
{
public:
B(){cout << "B()" << endl;}
~B(){cout << "~B()" << endl;}
void func(){
cout << "B::func()" << endl;
}
};
/****************************************
* 類名稱:Smart智慧指標模版類
****************************************/
template<typename T>
class SmartPointer
{
public:
//建構函式
SmartPointer(T * p = NULL):ptr(p){
}
//解構函式
~SmartPointer(){
if(ptr != NULL)
delete ptr;
}
//過載->運算子
T * operator->(){
return ptr;
}
//過載*運算子
T & operator*(){
return *ptr;
}
private:
T * ptr;
};
/****************************************
* 主測試函式main
****************************************/
int main()
{
SmartPointer<A> smt(new A());
smt->func();
(*smt).func();
SmartPointer<B> smtB(new B());
smtB->func();
(*smtB).func();
return 0;
}
下面是程式的輸出結果:
A()
A::fun()
A::fun()
B()
B::func()
B::func()
~B()
~A()
從輸出結果可以看出該模版類智慧指標也實現了管理堆物件的功能。
相關文章
- C++智慧指標C++指標
- 【C++】 61_智慧指標類别範本C++指標
- C++ 類成員指標C++指標
- C++進階(智慧指標)C++指標
- C++標準庫、C++標準模版庫介紹C++
- C++筆記(11) 智慧指標C++筆記指標
- c++ 智慧指標用法詳解C++指標
- c++ 類的函式引用 指標C++函式指標
- C++ 指標C++指標
- C++ this 指標C++指標
- C++標準庫有四種智慧指標C++指標
- C++ 用智慧指標這樣包裝 this 指標是否可行C++指標
- C++重寫C++
- 【C++】智慧指標的正確使用方式C++指標
- C++基於模板實現智慧指標C++指標
- C++指標理解C++指標
- C/C++指標總結C++指標
- 聊聊 C++ 中的幾種智慧指標 (上)C++指標
- C++(函式指標)C++函式指標
- C++中的this指標C++指標
- c++ 函式指標C++函式指標
- 詳解c++指標的指標和指標的引用C++指標
- C++智慧指標學習——小談引用計數C++指標
- c++智慧指標中的reset成員函式C++指標函式
- c++動態記憶體管理與智慧指標C++記憶體指標
- 1-7 C++指標C++指標
- C++基礎回顧4——智慧指標shared_ptrC++指標
- [C++] 成員函式指標和函式指標C++函式指標
- 【C++系列】指標物件和物件指標的區別C++指標物件
- 120 C++中的物件指標C++物件指標
- C++,繼承,基類和派生類指標間賦值等知識C++繼承指標賦值
- Redpanda:用C++重寫的KafkaC++Kafka
- C++ 指標常見用法小結C++指標
- C++智慧指標之shared_ptr與右值引用(詳細)C++指標
- C++11智慧指標用法C++指標
- C++定義函式指標,回撥C#C++函式指標C#
- C/C++高階訓練之指標初識C++指標
- C++ 智慧指標詳解: std::unique_ptr 和 std::shared_ptrC++指標
- c++指標傳遞與引用傳遞C++指標