2016-09-15 4 views
2

ここからは、一意のポインタを参照するときにポップアップする質問のほとんどを読んで分かりましたが、これはBuilderパターンで記述された動作を提供する必要があるようです。これはunique_ptrの正しい使い方ですか?

ビルド中のオブジェクトを所有するためにビルド中のオブジェクトを変更する手続きを実装していないため、ビルダーのインスタンス(またはそのサブクラス)が必要なのは、Closeが呼び出し側に一意のポインタを返すまでです呼び出し側が所有権を取得する点。

Builder.h

template <class type> class Builder 
{ 
public: 
    ~Builder(); 
    unique_ptr<type> Close(); 
protected: 
    Builder(); 
    unique_ptr<type> _uptr; 
}; 

Builder.cpp

template<class type> Builder<type>::Builder() 
{ 
    uptr = make_unique<type>(); 
} 

template<class type> Builder<type>::~Builder() 
{} 

template<class type> unique_ptr<type> Builder<type>::Close() 
{ 
    return uptr; 
} 

は値によってユニークなポインタを渡すの意味を、私理解していますか?

(含まれており、簡潔/読みやすさのために省略名前空間)

答えて

3

のstd :: unique_ptrを、コピーすることはできません。代わりに、基礎となるポインタの所有権を適切に移譲するためにuptrを移動する必要があります。

template<class type> unique_ptr<type> Builder<type>::Close() 
{ 
    return std::move(uptr); 
} 
+0

ありがとう:

は、ここで私はビルダークラスを変更したい方法です!それは理にかなっている。私は適切に転送を実行していなかったことを知っていました。 – ophilbinbriscoe

1

私は値でユニークなポインタを渡すの意味を理解していますか?

することはできunique_ptrをからmove:彼らは元のオブジェクトの内容を無効としてstd::move(this->_uptr)

が移動して注意してください。

私は脅威を例示するためにあなたの例を完了した:this->_uptrIntBuilder::Close()内で移動された

#include <iostream> 
#include <memory> 

template<typename T> class Builder 
{ 
public: 
    virtual ~Builder() {} 
    std::unique_ptr<T> Close(); 
protected: 
    Builder() {} 
    std::unique_ptr<T> _uptr; 
}; 

class IntBuilder: public Builder<int> 
{ 
public: 
    IntBuilder() : Builder<int>() { 
     this->_uptr = std::unique_ptr<int>(new int); 
    } 
    void setValue(int x) { 
     *(this->_uptr) = x; 
    } 
    std::unique_ptr<int> Close() { 
     return std::move(this->_uptr); 
    } 
}; 

int main() { 
    IntBuilder b; 
    b.setValue(3); 
    auto i = b.Close(); 
    std::cout << *i << std::endl; // OK 
    auto i2 = b.Close(); 
    std::cout << *i2 << std::endl; // Segmentation fault 
} 

が、コンパイラはとSegfaultの可能性について警告を表示しません。


さらに私は、クラスの後者だけ制限の柔軟性としてT Builder<T>::Close()代わりのunique_ptr<T> Builder<T>::Close()を使用してお勧めします。

また、作成しているインスタンスをサブクラスで管理しないようにしましょう。作成中のインスタンスに変更を加えることができない場合、サブクラスはインスタンスの情報を作成するまで(Close())、unique_ptr<T>を不必要に保持する必要があります。

template<typename T> class Builder 
{ 
public: 
    virtual ~Builder() {} 
    T&& Close(); 
protected: 
    Builder() {} 
}; 
+0

私は当初の定義の厳格な性質を明確に認識していました。これは、最終的にコースの成果物の一部になるため、C++によるデザインパターンの理解と使用に完全に重点を置いているためです。 – ophilbinbriscoe

+0

私はチームで働いており、私たちは皆新しい言語です。したがって、より基本的なユーザー定義型の厳密な使用パターンを持つことは、私の同僚のあいまいさを排除するかもしれません。 私はこのようなやり方の背後にある動機づけを見ています。これを読んで : http://stackoverflow.com/questions/5481539/what-does-t-double-ampersand-mean-in-c11は – ophilbinbriscoe

+0

私はまだ正確に閉じるリターンを何が起こっているかについて少しあいまいです。ビルダーインスタンスがMyClassBuilderであり、多数のメンバーを持つオブジェクトインスタンスを返し、いくつかの値、それらのポインタのいくつか、所有権はどうなりますか? T &&は内部を動かしてコピーを避けていませんか?それともTのインスタンスはテンポラリーなのでコピーしますか? – ophilbinbriscoe

関連する問題