古いソリューション
別の代入演算子はどうですか?
counted_ptr& counted_ptr::operator=(T* p)
{
if (! --*count) { delete count; }
pointer = p;
count = new int(1);
return *this;
}
...
one = new double(5);
また、デストラクタは常に共有ポインタを削除します。これがおそらく *one がランダムな番号になる原因です。おそらく、次のようなものが必要です。
counted_ptr::~counted_ptr() { if (! --*count) { delete pointer; delete count; } }
新しいソリューション
one = new double(5)
関連するすべての s を更新するためにcount_ptr (例: ) を再ポイントする必要があるcounted_ptr
ため、ポインターとカウントの両方をヘルパー クラスに配置し、ポインター クラスにヘルパー クラスへのポインターを保持させます (既にこのパスをたどっている可能性があります)。このデザインに記入するには、次の 2 つの方法があります。
- ヘルパー クラスを単純な構造体 (およびプライベート 内部クラス) にし、すべてのロジックを外部クラス メソッドに配置します。
ヘルパーcounted_ptr
クラスを作成します。counted_ptr
参照カウントを維持しますが、カウントを自動的に更新しません。release
これはスマート ポインターではなく、メッセージにのみ応答しretain
ます。Objective-C に少しでも精通している場合、これは基本的に従来のメモリ管理 (自動解放は別として) です。counted_ptr
参照カウントが 0 に達したときに自身を削除する場合としない場合があります (Obj-C との別の潜在的な違い)。counted_ptr
s はコピー可能であってはなりません。その意図は、単純なポインターの場合、最大で 1 つある必要があるということcounted_ptr
です。
smart_ptr
へのポインターを持つクラスを作成します。これは、同じプレーン ポインターを保持することになっているインスタンスcounted_ptr
間で共有されます。release メソッドと keep メソッドを送信して、カウントを自動的に更新する責任があります。smart_ptr
smart_ptr
counted_ptr
counted_ptr
のプライベート内部クラスである場合とそうでない場合がありshared_ptr
ます。
オプション 2 のインターフェイスを次に示します。これは演習として行っているので、メソッド定義を記入させてください。counted_ptr
潜在的な実装は、 のコピー コンストラクターとコピー代入演算子が必要ないこと、counted_ptr::~counted_ptr
呼び出しを行わないことcounted_ptr::release
(それがsmart_ptr::~smart_ptr
仕事です)、counted_ptr::release
解放counted_ptr::_pointer
されないこと (デストラクタに任せる場合があります)を除いて、既に投稿されているものと似ています。.
// counted_ptr owns its pointer an will free it when appropriate.
template <typename T>
class counted_ptr {
private:
T *_pointer;
size_t _count;
// Make copying illegal
explicit counted_ptr(const counted_ptr&);
counted_ptr& operator=(const counted_ptr<T>& p);
public:
counted_ptr(T* p=0, size_t c=1);
~counted_ptr();
void retain(); // increase reference count.
bool release(); // decrease reference count. Return true iff count is 0
void reassign(T *p); // point to something else.
size_t count() const;
counted_ptr& operator=(T* p);
T& operator*() const;
T* operator->() const;
};
template <typename T>
class smart_ptr {
private:
counted_ptr<T> *_shared;
void release(); // release the shared pointer
void retain(); // retain the shared pointer
public:
smart_ptr(T* p=0, int c=1); // make a smart_ptr that points to p
explicit smart_ptr(counted_ptr<T>& p); // make a smart_ptr that shares p
explicit smart_ptr(smart_ptr& p); // copy constructor
~smart_ptr();
// note: a smart_ptr's brethren are the smart_ptrs that share a counted_ptr.
smart_ptr& operator=(smart_ptr& p); /* Join p's brethren. Doesn't alter pre-call
* brethren. p is non-const because this->_shared can't be const. */
smart_ptr& operator=(counted_ptr<T>& p); /* Share p. Doesn't alter brethren.
* p is non-const because *this isn't const. */
smart_ptr& operator=(T* p); // repoint this pointer. Alters brethren
size_t count() const; // reference count
T& operator*() const; // delegate these to _shared
T* operator->() const;
};
うまくいけば、上記のあいまいな点は意図的なものだけです。