0

非 const 参照を取るコピー コンストラクターを持つクラスを一時オブジェクトからコピー構築できるようにするにはどうすればよいですか?

背景はこうです。

Base からすべて継承するオブジェクトへのポインターのリストを返す関数があるため、vector<Base*>. それはあまり選択肢ではないので、デストラクタ内のすべての要素を削除vector<auto_ptr>する単純なラッパーを書きたいと思いました。vector<Base*>

私は次の問題に直面しています:

私のクラスには、次のようなコピー コンストラクターがあります。

auto_list(auto_list& rhs);

ポインタ リストを新しいインスタンスにコピーし、古いインスタンスでクリアできるようにします。

しかし、明らかに、一時変数は非定数参照にバインドされないため、戻り値では機能しません。関数から auto_ptr を返すことができるのを見て、どのように実装したのでしょうか?

注: 私は C++11 やブーストを使用できないため、ムーブ セマンティクスや unique_ptr はオプションではありません。

それが役立つ場合、これはこれまでの私のコードです:

template <typename T> class auto_list
{
private:

    vector<T*> pointers;

public:

    auto_list(vector<T*>& pointers)
    {
        this->pointers = pointers;
    }

    auto_list(auto_list& rhs)
    {
        this->pointers = rhs.pointers;
        rhs.pointers.clear();
    }

    ~auto_list()
    {
        for(typename vector<T*>::const_iterator it = this->pointers.begin(); it != this->pointers.end(); it++)
        {
            delete (*it);
        }
    }

    auto_list& operator=(auto_list& rhs)
    {
        this->pointers = rhs.pointers;
        rhs.pointers.clear();
    }

    vector<T*> get_pointers() const
    {
        return this->pointers;
    }
};
4

4 に答える 4

3

このクラスは、それ自体と同様に、使用するのがかなり混乱するため、auto_ptrより賢明なスマート ポインターを使用することをお勧めします。Boost を使用しない正当な理由がある場合でも (私の人生では、なぜ使用しないのかわかりません)、どうstd::tr1::shared_ptrですか?

このコースを受講することに決めた場合はauto_ptr、参照をクラス ( ) でラップすることにより、一時的なものから初期化する問題を解決しますauto_ptr_ref。ラッパーは変換関数 from *this(左辺値であるため、非 const 参照にバインドできます) によって作成され、値によってコンストラクターに渡すことができます。

同様のことができます:

template <typename T> class auto_list_ref
{
    friend class auto_list<T>;
    auto_list_ref(auto_list<T> & ref) : ref(ref) {}
    auto_list<T> & ref;
};

template <typename T> class auto_list
{
public:
    // Add a constructor and conversion operator as follows:

    auto_list(auto_list_ref<T> rhs)
    {
        this->pointers = rhs.ref.pointers;
        rhs.ref.pointers.clear();
    }

    operator auto_list_ref<T>() {return auto_list_ref<T>(*this);}
};

これがデモンストレーションです。

于 2012-01-12T18:47:47.177 に答える
2

右辺値参照が考案された全体的な理由は、これが C++03 では機能しないためです。つまり、根本的に、完全に、壊れています。あなたはできない何かと戦おうとしています。戻り値またはヒープ割り当てポインターを渡すことに固執します。

于 2012-01-12T18:32:44.567 に答える
1

pointersas として宣言mutableできるため、copy ctor と割り当て操作を take として宣言してconst auto_list &も、clear を呼び出すことができます。ただし、コピーするとコピー元のオブジェクトがクリアされるため、結果のクラスは慎重に使用する必要があります。

于 2012-01-12T18:41:25.843 に答える
0

std::vector<auto_ptr<Base>>auto_list での不足を回避しているだけの場合は、クラスを完全に削除して、 で機能する独自のカウント ポインターを作成することをお勧めしますstd::vector。の共通オブジェクトを格納することだけが必要な場合はBase、参照カウントにすることもできるため、コードは現在作成しているカスタム リストよりも少なくなります。

これがうまくいかない場合、unique_ptr<>C++11 より前に標準で処理されていた壊れた方法を採用するのがおそらく 2 番目に良い選択です。つまり、a を渡して、その上で aconst referenceを実行const_castします (うん!!!)。これを決定する場合は、セマンティクスが常に正しくなるように非常に注意してください (const が const でないことによって十分に壊れます)。

于 2012-01-12T18:44:19.620 に答える