2017-02-07 6 views
0

私はC++ 11プロジェクトに取り組んでいます。その中に私はを持っていますstd::stringデータ。shared_ptrを使用する場合、デストラクター、コピーコンストラクター、代入演算子を実装する必要があります

class Base { 
public: 
    Base() : Base(string()) {} 
    virtual ~Base() = default; 
    Base(const string &str) { 
    str_ = std::make_shared<string>(str); 
    } 
private: 
    std::shared_ptr<std::string> str_; 
}; 

私の質問は:ここで私はコピーの世話をするために、コンストラクタと代入演算子をコピーし、str_を解放するデストラクタを実装する必要がありますか? コンパイラが提供するデフォルトのものに頼っていれば十分ですか? は、私が「正しい」となりますBase *b1 = new Base("string");

+2

いいえ、作成する必要はありません。 –

+0

なぜ文字列を保持するためにshared_ptrを使用していますか?あなたは本当にこのオブジェクトのコピーが非常に同じ文字列を参照するようにしますか?もしそうなら、なぜですか? –

+3

デフォルトで提供される単純なmemberwise-copyが十分であるため、コンパイラによって提供されるデフォルトの実装に頼ることができます。 –

答えて

1

デフォルトコンストラクタと代入演算子(コピーと移動の両方)によってBase b1("string");またはヒープにスタック内のいずれかで、このクラスのオブジェクトを作成できるようにしたいです。具体的に

Base *p1 = new Derived1("foo", "bar"); 
Base *p2 = new Derived1("bar", "foo"); 
*p1 = *p2; // Will compile, but probably won't do what you want. 

:私は引用符で「正しい」を入れた理由は、私はあなたが(仮想デストラクタを与え、そして名)このBaseクラスからクラスを派生する予定の懸念を持っており、あなたのような何かを書く場合ということです割り当てによってp2が指すオブジェクトの一部のBaseがコピーされますが、の部分はコピーされません。

私は、コンストラクタと代入演算子を削除したり、それらを保護したりします。

class Base { 
public: 
    Base() : Base(string()) {} 
//Either 
    Base(const Base& rhs) = delete; 
    Base& operator=(const Base& rhs) = delete; 
//OR 
protected: 
    Base(const Base&rhs) = default; 
    Base& operator=(const Base& rhs) = default; 
    Base(Base&&rhs) = default; 
    Base& operator=(Base&& rhs) = default; 
public: 
//END 
    virtual ~Base() = default; 
    Base(const string &str) { 
    str_ = std::make_shared<string>(str); 
    } 
private: 
    std::shared_ptr<std::string> str_; 
}; 
+0

はい、私はそれから派生したクラスを作成します あなたは精巧にしてください、なぜ私はそれらを "保護する"か、それらを無効にする必要がありますか? ありがとう – RuLoViC

+0

そうしないと、 '* p1 = * p2'は基底クラスの値*を割り当てますが、派生した要素!*は割り当てません。私は答えを編集した –

関連する問題