スマートポインタのソースコード解析atuo_ptr

ヒープメモリは手動でのみ開くことができますようにのC ++には、何のガベージコレクションではありませんので、手動解除システムは、メモリリークの防止、スタック、システムのリリース、手動で開かれ、システムがリリースされたメモリを実装してスマートポインタの出現、のように開くことができます;

私たちは、あなたがして、結合メモリの束とスタックオブジェクトを検討し、そのデストラクタでヒープメモリを解放することができますので、その範囲を残しスタックオブジェクトは、デストラクタは、自動的に呼び出されていることを知っていますオブジェクトがスコープ・スタックの外にあるとき、ヒープメモリは自動的にスマートポインタ(基本的にスタックオブジェクト)の原則である、解放されます。このテーマのようにしようとすると、スタック・ポインタのように見えるので、私たちは、実際には、それだけで一般的なスタックはオブジェクトのみだった、スマートポインタを呼び出します。 

C ++ 98では、唯一の自動PTR、このポインタは不完全で、今はほとんど放棄されているが、我々はまだそれが放棄されるべき理由を理解し、彼が考えているかを理解する必要がありますか?そして、彼はC ++ 11それを改善する方法をどのようにでしょうか?

//ポインタが自動的にauto_ptrはすなわち、ポインタが自動的にポインタを使用する権利譲渡scoped_ptrを異なる
元のauto_ptrは、ポインタ管の所有権を失う、割り当てまたはコピーを実行した後//構成を、そのポインタが形成NULLであります
/構成をコピー割付後および/一方、ポインタがNULLを指すであろうオリジナルauto_ptrには、それはまた、最大の欠点の一つです。

#include <iostreamの>
使用して名前空間STD;


//単純な
クラスA
{
パブリック:
ボイド楽しい()
{

}
};


テンプレート<クラスT>

//クラステンプレート
クラスauto_ptrは
{
パブリック:

//コンストラクタの明示的な禁止型変換
明示auto_ptrは(T * P = 0)投()
:(!P = 0)m_bIsOwner、m_ptr(P)
{
COUT << "DEBUG1" << ENDL;
}

//所有者転送
auto_ptrを(CONST auto_ptrを<T>& Y) 投()
:m_bIsOwner(y.m_bIsOwner)、m_ptr(y.release())
{
COUT << "DEBUG2" << ENDL;
}

//所有者転送
auto_ptrを<T>&演算子=( CONST auto_ptrを<T>&y)を投()
{
<< COUT "DEBUG3" << ENDL;

IF(!=&このY)Y //現在のオブジェクトがオブジェクトではない
{
COUT << "debug4" << ENDL;

IF(!= m_ptr y.get())//現在のオブジェクトYアドレスアドレスがバインドされたオブジェクトにバインドされていない
{
COUT << "debug5" << ENDL;

IF(m_bIsOwner)//現在のオブジェクトがすでにスタックを結合した場合、最初のリリース
{
COUT << "debug6" << ENDL ;
; m_ptr削除
}

COUT << "debug7" << ENDL;

//転送所有者; m_bIsOwner = y.m_bIsOwnerを
}
(y.m_bIsOwner)Y //現在のオブジェクトと同じものにヒープ結合、及びYである場合には他所有者、オブジェクト転送yの現在の所有者に置く
{
COUT << "debug8" << ENDL;

m_bIsOwner = trueに;
}

COUT << "debug9" << ENDL。

m_ptr = y.release(); // yはもはやそう所有者である
}

COUT << "debug10" << ENDL。

*これは返します。現在のオブジェクトへの参照を返す//
}

//デストラクタ
〜auto_ptrを()
{
COUT <<「debug11」<<てendl;

//唯一の財産所有者は、このように自由に複製避け、スタックをリリースしていないIF(m_bIsOwner)
{
COUT <<「debug12」<< ENDLは、

m_ptr削除; // NULLポインタもさえm_ptr関係木材である
}
}

// *オブジェクトをオーバーロードオペレータオブジェクトがポインタのように、実行することができる「見える」ように、* P操作
T&演算子*())(スローCONST
{
<< "debug13" << ENDL COUTと、

* GET()を返す;
}

//過負荷オブジェクト- >演算子
のT *演算子- >()スローCONST()
{
<<裁判所未満"debug14" <<てendl;

リターンGET();
}

//オブジェクトバインドのアドレス取得
のT *のGETは()スロー()constは
{
COUT << "debug15" <<てendlを、

m_ptrを返します。
}

//オブジェクトの所有者の財産削除
T *リリースを()スローをCONST()
{
COUT << "debug16" <<てendl;

((auto_ptr を<T> *)この) - > = m_bIsOwner falseに、
m_ptrを返す;
}

プライベート:
BOOL m_bIsOwner; //オブジェクトが所有者フラグによって所有され
たT *のm_ptr; //ポインタは、結合オブジェクトへ
};


int型のmain()
{
{
COUT <<「--------------- ---------------「<< ENDL;

//使用エラー、明示的なコンストラクタが存在するため、型変換が許可されない
// auto_ptrは<整数> P =新しい INT(10)。
}


{
COUT << "------------------------------" << ENDL;

// OK
auto_ptrは<整数> P( INT新しい新しい(10));
}


{
COUT << "------------------------------」<<てendl;

//次のコードは、重度のランタイムエラーがあり、実際のスタックの内容を削除しようと
int型A = 10;
// auto_ptrは<整数> P(&A);
}


{
COUT <<「-------- ---------------------- "<<てendl;

auto_ptrは<整数>のp-(新新int型(10));

//エラー、Pが"それはのように思えます「P削除対象の本質であるポインタが、未定義の動作である
; //削除P
}


{
------------------------ COUT <<」 ------「<<てendl;

int型= Q *新しい新しいINT(10);
auto_ptrは<整数> P(Q);

//エラーは、qは繰り返し、一度Pのリリースを発表しているリリースああ
//削除Q;
}


{
COUT << "------------------------------" << ENDL;

auto_ptrは<整数> P0;

//存在DEBUG3印刷、ないdebug4、知っているなぜそれ
P0 = P0;
}


{
COUT << "------------------------------" << ENDL。

auto_ptrは<整数> P0(新しい新しいINT(10));

//この初期化は、コピーされていないので、何も印刷DEBUG3が存在しないことに注意してください
。auto_ptrは<整数> P1 = P0
}


{
COUT <<「----- -------------------------「<< ENDL;

auto_ptrは<整数> P0(新しい新しいINT(10));
auto_ptrは<整数> P1;

/ /、これは割り当てであることをすべて持っているDEBUG3、debug4、debug5、debug7、注意 debug9、debug10の印刷を
// debug6なぜそれがなかったですか?これは、オブジェクトP1の所有者ではないので
、P1 = P0;
}


{
COUT << "------------------------------" << endl;

auto_ptrは<整数> P0(新新int型(10));
auto_ptrは<整数> P1(新しい新しいint型(20));

//プリントdebug6ヘッドリリースオブジェクトを結合P1ので、そうでない場合は、メモリが漏れたああ
P0 = P1;
}


{
COUT << "------------------------------" < <てendl;

auto_ptrは<整数> P0(新しいint型(10));

//所有者P1に転送
auto_ptrは<整数> P1(P0);

//最後にdebug8、お会い
P0 = P1;
}

{
COUT <<「--------------- ---------------「<<てendl;

auto_ptrは<整数>のp-(新新int型(10));

//お会いし、debug13
coutの<<てendl << * p型;
}


{
COUT << "------------------------------" << ENDL;

auto_ptrは<A> P(新新A( ));

//最後にお会いし、debug15
のp->楽しい();
}


{
COUT <<「------------------------- -----「<<てendl;

auto_ptrは<整数> P0(新新int型(10));
auto_ptrは<整数> P1(P0);
auto_ptrは<整数> P2(P1);

//実際には、P3が最後であります勝者は、最終所有者です、したがって、P3積層体を放出するタスク
auto_ptrは<整数> P3(P2);
}


{
<<裁判所未満"------------------------------" <<てendl;

// OH、私の神、メモリリーク、もともと[] Qを削除し、今だけQ行うデストラクタは削除;
INT = Q *新しい新しいINT [3];
auto_ptrは<整数> P(Q);
}


{
COUT <<「---------- --------------------「<<てendl;

// OH、私の神、メモリリークは、[]のqを削除することでしたが、今行っデストラクタは唯一のqを削除します;
int型* Q =新しい新しいのint [3];
auto_ptrは<整数> P-(Q);

//すでに次の文は、メモリ解放されます繰り返し、言った
; //削除Q
}


//最後にauto_ptrには、コンテナに適していない、説明私たちがして後で再検討する要素、


0を返します。

}

オリジナルリンクします。https://blog.csdn.net/stpeace/article/details/45155487

ブログと良いテストケース、非常に明確な考え

おすすめ

転載: www.cnblogs.com/xcb-1024day/p/11331117.html