0

私は本でこのコード、単純なスマート ポインターに出くわしました。それについていくつか質問があります。

    template <class T>
class SmartPointer {
 public:
    SmartPointer(T * ptr) {
        ref = ptr;
        ref_count = malloc(sizeof(unsigned));
        *ref_count = 1;
    }
    SmartPointer(SmartPointer<T> & sptr) {
        ref = sptr.ref;
        ref_count = sptr.ref_count;
        ++*ref_count;
    }
    SmartPointer<T> & operator=(SmartPointer<T> & sptr) {
        if (this != &sptr) {
           ref = sptr.ref;
           ref_count = sptr.ref_count;
           ++*ref_count;
        }
        return *this;
    }
    ~SmartPointer() {
        --*ref_count;
        if (*ref_count == 0) {
           delete ref;
           free(ref_count);
           ref = ref_count = NULL;
        }
    }
    T* operator->() { return ref; }
    T& operator*() { return *ref; }
 protected:
    T * ref;
    unsigned * ref_count; 
};

ここに私の質問があります: 1. ref_count が malloc を使用して初期化されるのはなぜですか? なぜできないのですか ref_count = new unsigned(); 2. = 演算子関数、古い値をクリーンアップする必要はありませんか? このコードは参照カウント エラーを引き起こすようです。

ありがとう、

4

3 に答える 3

3

あなたが持っているこの本はゴミです。あなたはそれを捨てる必要があります。このコードはコンパイルさえしません。

  1. mallocよりも優れているわけではありませんnew unsigned(1)。キャストする必要があるmalloc()戻り値は、明らかにここでは行われません。void*unsigned*
  2. そうです、以前に指されたオブジェクトの参照カウントを処理する必要があります。

orの実装を調べてみませんboost::shared_ptrstd::shared_ptr?いずれにせよ、それを使用することになる可能性が非常に高いです。

于 2012-08-29T04:55:20.397 に答える
1

これは悪いコードです。自己代入は慣用的ではなく、 のひどい使用法でありmalloc、バグのある参照カウントの実装であり、コピー代入演算子/コンストラクターの引数ではなく、NULL を指す s をconst処理しません。SmartPointerあなたの本を捨てて、うまくいく本を手に入れてください。

于 2012-08-29T05:06:44.520 に答える
1

を使用して ref_count が初期化されるのはなぜmallocですか?

こちらも使えstd::newます。との主な違いはnew、動的メモリの割り当てに加えて、コンストラクターを呼び出すことにより、オブジェクトを適切に初期化する機会を提供することです。(コード例のように) 組み込みのデータ型の場合、malloc本質的にこの重要な違いは重要ではありません。 . 通常、実装は基本的にメモリ割り当てのために も呼び出すことに 注意してください。newunsigned int
std::newmalloc

= operator関数、古い値をクリーンアップする必要はありませんか? このコードは参照カウントエラーを引き起こすようです

確かにエラーがあります。
この実装の は、ポインタがそれ自体に割り当てられているかどうかをチェックし、割り当てられている場合は、が呼び出された後にこのポインタを共有するエンティティがもう 1 つあるため= operator、参照カウントを だけ正しく増やします。 シナリオが自己割り当てでない場合、実装は によって割り当てられているポインターの参照カウントを減らし、カウントがゼロであるかどうかを確認し、ゼロの場合は同じものを解放する必要があります。1=
10

于 2012-08-29T04:26:41.667 に答える