2

スマートポインタのインスタンスをコンテナに保存するのに問題があります。ポインタのコードは次のとおりです。

#include "std_lib_facilities.h"

template <class T>
class counted_ptr{
private:
    T* pointer;
    int* count;

public:
    counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {}    // default constructor
    explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
    ~counted_ptr()
    {
        --*count;
        if(!*count) {
            delete pointer;
            delete count;
        }
    }

    counted_ptr& operator=(const counted_ptr& p)    // copy assignment
    {
        pointer = p.pointer;
        count = p.count;
        ++*count;
        return *this;
    }
    T* operator->() const{ return pointer; }
    T& operator*() const { return *pointer; }
    int& operator[](int index) { return pointer[index]; }

    int Get_count() const { return *count; }    // public accessor for count


};




int main()
{
    counted_ptr<double>one;
    counted_ptr<double>two(one);
    one = new double(5);
    vector<counted_ptr<double> >test;
}

int main()では、vector<counted_ptr<double> >行はコンパイルされます。最初に試したときvector<counted_ptr<double> >はコンパイルされませんでした(おそらくパラメーターが不足していたためです)。ただし、次のようなpush_backを使用しようとすると

test.push_back(one);

vector.tccを開くコンパイラエラーが発生し、特定のエラーが発生します。

no matching function for call to `counted_ptr<double>::counted_ptr(const counted_ptr<double>&)'|

push_backはcounted_ptrを見つけることができないと思いますが、本当にわかりません。どんな助けでもありがたいです、ありがとう。

編集:ただし、これは機能します。test [0] =1; push_backのセマンティクスがそれを制限していると思います。

4

2 に答える 2

5

これを試してみてください:

test.push_back(counted_ptr<double>(one));

コンストラクターを明示的にコピーします。つまり、コンパイラーはそれを暗黙的に呼び出しません。

個人的には、生のポインター コンストラクターを明示的にし、コピー ctor を明示的にしません。その方が普段の行動に近いでしょう。

編集: swap メソッドを実装することもお勧めします。それは割り当てを絶対に簡単にします。次のような結果になります。

counted_ptr &operator=(const counted_ptr &rhs) {
    counted_ptr(rhs).swap(*this);
    return *this;
}

これには、コンストラクター/デストラクターで発生するすべてのアカウンティングの利点もあり、管理がはるかに簡単です:-)。

于 2009-08-22T18:09:55.910 に答える
3

代入演算子が間違っています。
それが指していたオブジェクトに何が起こったのですか?
自分自身または同じ内部オブジェクトに割り当てている場合はどうなりますか?

counted_ptr& operator=(const counted_ptr& p)    // copy assignment
{
    if (&p != this)
    {
        --*count;
        if ((*count) == 0) // Much more readable than !*count
        {
            delete pointer;
            delete count;
        }
        pointer = p.pointer;
        count = p.count;
        ++*count;
    }
    return *this;
}

注: 独自のスマート ポインターを作成することはお勧めできません。それらは、あなたが考えるほど書くのは簡単ではありません。

注:これは私が最初に見つけたものです。もっとあるかもしれませんが、これが 100% 正しいかどうかはわかりません。

実際、コピー/スワップ idium を使用するように代入演算子を変更します。

counted_ptr& operator=(const counted_ptr& p)    // copy assignment
{
    counted_ptr<T>     tmp(p);   // increment counter on p
    swap(tmp.pointer, pointer);
    swap(tmp.count    count);

    return *this;
                                 // tmp goes out of scope and thus the
                                 // destructor gets called and what was in this
                                 // object is now destroyed correctly.
}
// It may even be worth writing your own swap operator.
// Make sure you declare it as no-throw and grantee it.
于 2009-08-22T18:11:25.097 に答える