スマートポインタ——《C++Primer》Chapter 14
最近C++の勉強を始め、読み直してずっと読んでいないC++Primer.
本のコードや練習問題を叩いたり、拡張したりします.
ここでいくつかの総括と記録をして、本を読むノートでしょう.
###############################################################
概要:
Chapter 14は主にいくつかのオペレータのリロードの問題について話した.
IOリロードはなぜ友元関数を使うのですか?前++と後++の重荷重はどのように区別しますか?
*、->をリロードするときはconstと非constの2つのバージョンを実装したほうがいいです.
->重荷、いったい何をコンパイルしたのか、O(∩∩)O~
この2,3日スマートポインタを見て、手がかゆくて簡単なバージョンを実現しました:referenceカウントに基づいて実現しました
カウンタを元のヌードポインタにバインドし、スマートポインタにカプセル化することです.
このようなメリットは、newが出てきたものは、いつdelete、スマートポインタに関心を持つ必要はありません.
すべてを手伝ってあげることができます.(相互参照はしばらく考慮しない)
汎用性を持つためにtemplateと書いてみましたが、templateのコードを使っているかどうか分かりません.
必ずすべてヘッダーファイルに入れますか?指図を求める.
カウンタ:
このクラスは外部の人に見られたくないのでprivateにしてSmartPtrを友元クラスにします.
P.S.友元类を宣言する时templateとfriendの顺番、私は来て反対して、C++はよく知らないで、ほほほ.
スマートポインタ:
1.コピーコンストラクタを再ロードし、参照数を増やす
2.構造関数を再ロードし、参照カウントを減らして0かどうかを判断しdelete
3.重荷付与操作、処理カウント、P.S.処理手順が適切であれば、自身付与問題であるか否かを判断する必要はない、ほほほ.
4.スマートポインタを1つのポインタのように表現するには、次のオペレータを再ロードします.
テスト:
出力結果:
ソース:
https://github.com/niaokedaoren/CPP_Primer/tree/master/Chapter14/SmartPointer
本のコードや練習問題を叩いたり、拡張したりします.
ここでいくつかの総括と記録をして、本を読むノートでしょう.
###############################################################
概要:
Chapter 14は主にいくつかのオペレータのリロードの問題について話した.
IOリロードはなぜ友元関数を使うのですか?前++と後++の重荷重はどのように区別しますか?
*、->をリロードするときはconstと非constの2つのバージョンを実装したほうがいいです.
->重荷、いったい何をコンパイルしたのか、O(∩∩)O~
この2,3日スマートポインタを見て、手がかゆくて簡単なバージョンを実現しました:referenceカウントに基づいて実現しました
カウンタを元のヌードポインタにバインドし、スマートポインタにカプセル化することです.
このようなメリットは、newが出てきたものは、いつdelete、スマートポインタに関心を持つ必要はありません.
すべてを手伝ってあげることができます.(相互参照はしばらく考慮しない)
汎用性を持つためにtemplateと書いてみましたが、templateのコードを使っているかどうか分かりません.
必ずすべてヘッダーファイルに入れますか?指図を求める.
カウンタ:
template <typename T> class SmartPtr;
class SPtrCounter
{
template <typename T> friend class SmartPtr;
int counter; // reference counter
SPtrCounter(int n = 1): counter(n) {}
void incRef() { counter++; }
void decRef() { counter--; }
int refNum() { return counter; }
};
このクラスは外部の人に見られたくないのでprivateにしてSmartPtrを友元クラスにします.
P.S.友元类を宣言する时template
スマートポインタ:
1.コピーコンストラクタを再ロードし、参照数を増やす
SmartPtr(const SmartPtr<T> &origin):
objPtr(origin.objPtr), counter(origin.counter)
{
counter->incRef();
print("Copy Constructor");
}
2.構造関数を再ロードし、参照カウントを減らして0かどうかを判断しdelete
~SmartPtr()
{
counter->decRef();
print("Deconstructor");
if (counter->refNum() == 0)
{
delete counter;
delete objPtr;
std::cout << "Released memory: " << objPtr << std::endl;
}
}
3.重荷付与操作、処理カウント、P.S.処理手順が適切であれば、自身付与問題であるか否かを判断する必要はない、ほほほ.
template<typename T>
SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T> &rhs)
{
print("Before assignment");
rhs.counter->incRef();
counter->decRef();
if (counter->refNum() == 0)
{
delete counter;
delete objPtr;
std::cout << "Released memory: " << objPtr << std::endl;
}
objPtr = rhs.objPtr;
counter = rhs.counter;
print("After assignment");
}
4.スマートポインタを1つのポインタのように表現するには、次のオペレータを再ロードします.
T& operator*();
T* operator->();
const T& operator*() const;
const T* operator->() const;
テスト:
#include <iostream>
#include <string>
#include "SmartPointer.h"
using namespace std;
class Person
{
public:
static SmartPtr<Person> getInstance(const string &name);
Person(const string name=""): name(name)
{
cout << name << "'s constructor is invoked" << endl;
}
void print()
{
cout << "My name is " << name << endl;
}
~Person()
{
cout << name << "'s deconstructor is invoked" << endl;
}
private:
string name;
};
SmartPtr<Person> Person::getInstance(const string &name)
{
return SmartPtr<Person>(new Person(name));
}
int main()
{
SmartPtr<Person> sp1 = Person::getInstance("Jack");
SmartPtr<Person> sp2 = Person::getInstance("Tom");
cout << "***Test auto releasing***" << endl;
{
SmartPtr<Person> newSptr = sp1;
(*newSptr).print();
}
sp1->print();
cout << "***Test assignment***" << endl;
sp1 = sp2;
sp1->print();
return 0;
}
出力結果:
Jack's constructor is invoked
Constructor: 0x8aae020, refNum: 1
Tom's constructor is invoked
Constructor: 0x8aae078, refNum: 1
***Test auto releasing***
Copy Constructor: 0x8aae020, refNum: 2
My name is Jack
Deconstructor: 0x8aae020, refNum: 1
My name is Jack
***Test assignment***
Before assignment: 0x8aae020, refNum: 1
Jack's deconstructor is invoked
Released memory: 0x8aae020
After assignment: 0x8aae078, refNum: 2
My name is Tom
Deconstructor: 0x8aae078, refNum: 1
Deconstructor: 0x8aae078, refNum: 0
Tom's deconstructor is invoked
Released memory: 0x8aae078
ソース:
https://github.com/niaokedaoren/CPP_Primer/tree/master/Chapter14/SmartPointer