2016-03-29 3 views
1

、彼は書いている:クラスに移動のみのタイプを追加すると、そのクラスは移動のみのタイプになります。スコットマイヤーズ 『効果的な現代のC++』で

それはstd::mutex(すなわち、 ことができるタイプが移動しますが、コピーされません)移動専用型であるため、何も価値がある、A mPolynomialに追加する副作用は、Polynomialがコピーする能力を失うことです。しかし、まだ移動することができます。ここで

、彼は(マルチスレッドながら)1クラスのconstメンバ変数へのアクセスを保護しなければならない理由を説明の文脈でクラスPolynomialにメンバ変数としてstd::mutex mを追加します。彼が説明した概念を理解しました。私はもう少し説明する必要があるのは、なぜクラスに移動のみのタイプを追加すると、そのクラスはコピー可能ではない移動可能なタイプになるのですか?std::mutexstd::atomicのような型はデフォルトでは移動型ですか?私たちのクラスに変数の型を移動するだけでコピーを実行したいのであれば、どうすればそれを乗り越えることができますか?

+0

「なぜstd :: mutexはコピー不可能なのですか」、または「コピー不可能なメンバを追加するとクラスをコピー不可能にするのはなぜですか」という疑問ですか? – Barry

+0

Barry、両方の質問の答えを得る –

+1

'mutex'を含む型のコピーとメンバの移動方法:http://stackoverflow.com/a/29988626/576911 –

答えて

1

std::mutexは、標準でそう書いているのでコピーできません。彼らはコピー可能なstd::mutexを書いた可能性がありますが、そうでないと決めました。

コピー不可能なstd::mutexは、より効率的で、安全で、わかりやすいかもしれません。

例として、より安全で理解しやすい理由は次のとおりです。std::mutexがロックされているとはどういう意味ですか?個人的には、正しい答えが何であるか分かりません。私は正解が "それはナンセンス"だと思う。 「少なくとも驚きの答え」はありません。

並行処理コードで驚くべき回答をする代わりに、コピーをブロックすることで質問を回避します。コピーしたいミューテックスを格納している人は、自分が望むものを自分で決める必要があります。


C++では、コピーコンストラクタが自動的に生成されることがあります。より多くの状況では、それはあなたがそれを求めるときにMyClass(MyClass const&)=defaultと1つを書くことができます。

クラスにコピー不可能なクラスが含まれている場合、クラスにはコピーできません。生成できません。そのクラスは要求できません。これは、生成されたコピーコンストラクタが基本的にメンバーをコピーするためです。メンバをコピーできない場合は、コピーコンストラクタを生成できません。


したがってmutexは標準でそう言いますからコピーできません。

構造体またはクラスにコピーできないメンバーが含まれている場合、デフォルトのコピーコンストラクタは使用できません。自分自身を明示的に書く必要があります。


あなたのタイプは、そのほかのメンバーの手動コピーがすべてのサブ構造体にあなたの非mutex状態を固執することですコピーctorのを維持することの頭痛を防ぐためにmutex、1つのアプローチを保存する必要がある場合その既定のコピーを使用します。次に、コピー中にmutexをどうすればよいかを決定し、コピーctor(および代入コピー演算子)は単純なままです。

struct bob_with_mutex { 
    sturct bob_simple_data { 
    int x, y, z; 
    std::vector<char> buff; 
    }; 

    bob_simple_data data; 
    std::mutex m; 

    bob_with_mutex(bob_with_mutex const& o): 
    data(o.data) 
    {} 
    bob_with_mutex& operator=(bob_with_mutex const& o) 
    { 
    data = o.data; 
    return *this; 
    } 
}; 

タイプbobには、ミューテックスといくつかのデータが混在しています。データはサブ構造に格納されます。 bob_with_mutexのコピーctorはデフォルトにすることはできませんが、単に "データをコピーするだけです"と表示されます。

bobのコピーには独自のミューテックスがあります。

+0

"std :: mutexもstd :: atomicsもmove-onlyではありません。コピー可能でも移動可能でもないので、クラスを含むクラスはコピー不可と移動不可の両方にレンダリングされます。 –

+1

@RichardGeorge 「移動不可」を削除し、「コピー不可」に置き換えました。コピー不可能なメンバを含むクラスはコピーできますが、*デフォルトで生成されたコピーコンストラクタは暗黙的に削除されます*。 – Yakk

+0

私はそれを得ることができなかったので、簡単な統語構造で行の最後のブロックを精巧にすることができますか? –

2

は「クラスへの移動のみのタイプを追加する理由にのみコピーできないタイプの動きとして、そのクラスを作る」

これはentierly真実ではありません。非コピー可能メンバ変数を追加するとType (const Type& t) = default;のようなものを書くことからあなたを防ぐことができますが、それでもあなたにこれ以外

class Type{ 

int integer; 
std::mutex m; 

public: 
Type() = default; 
Type(const Type& rhs): integer (rhs.integer){} 

} 

非コピー可能メンバーを無視する独自のコピーコンストラクタを実装することができ、あなたはmove-を含むオブジェクトの多くの例を見つけることができますメンバだけですが、開発者がムーブコンストラクタを削除したため、移動できません。

なぜstd :: mutexとstd :: atomicのような型はデフォルトでは移動型ですか?

どちらも移動コンストラクタを実装していません。これは間違った発言です。

+0

Davidありがとう!しかし、あなたはstd :: mutexは移動型ではないと言っていましたか?それは私が読んだものよりも矛盾しているようです。 –

+0

mutexがmove/copiableであることを理解した段落を正確にコピーすると、 –

+0

DavidのStd :: Mutexのコンストラクタを調べると、mutex(const mutex&)= deleteと表示されます。そのため、明らかに特殊メンバーの移動機能が生成される可能性があります。 –

0

1つの可能性は、ミューテックスタイプをミューテックスへのポインタに変更することです。ポインタはコピーできますが、mutexのコピーは1つだけです。スマートポインタを使用することができます。

+0

ミューテックスを保持するスマートポインタは私には意味がありません。 – Ajay

関連する問題