2017-07-09 2 views
3

私はRule of Zeroについて読んでいます。ゼロの混乱のルール?

簡体字:このルールの目的はわかりません。 3と5のルールは、「経験則」のようなものですが、このルールでは「経験則」や他の具体的な意図を見ることはできません。

詳細バージョン:

引用私にしてみましょう:カスタムデストラクタ、コピー/移動コンストラクタや コピー/移動代入演算子は、所有権を独占的に対処すべきを持って

クラス。 他のクラスでは、カスタムデストラクタ、コピー/移動 コンストラクタ、またはコピー/移動代入演算子は使用できません。

これはどういう意味ですか?彼らは何を意味するのですかオーナー、何の所有権ですか? 彼らはまた、サンプルコード(私はそれが導入に接続されていると思います)を示しています

class rule_of_zero 
{ 
    std::string cppstring; 
public: 
    rule_of_zero(const std::string& arg) : cppstring(arg) {} 
}; 

彼らがこれを表示するために何をしたいかを、私は本当にこの1に失われています。

また、ポリモーフィッククラスを扱っており、デストラクタがpublicおよびvirtualとして宣言され、このブロックが暗黙的に移動するというシナリオについても説明しています。そのため、あなたに不履行それらすべてを宣言する必要があります。

class base_of_five_defaults 
{ 
public: 
    base_of_five_defaults(const base_of_five_defaults&) = default; 
    base_of_five_defaults(base_of_five_defaults&&) = default; 
    base_of_five_defaults& operator=(const base_of_five_defaults&) = default; 
    base_of_five_defaults& operator=(base_of_five_defaults&&) = default; 
    virtual ~base_of_five_defaults() = default; 
}; 

これはあなたが公共および仮想の両方で宣言されたデストラクタを持つ基底クラスを持っている時はいつでも、あなたが本当にすべての他の特別なメンバ関数を宣言しなければならないことを意味していますデフォルトでは?もしそうなら、なぜ私は見ません。

私はこれが1つの場所で多くの混乱であることを知っています。

+0

所有権==管理対象リソースのライフサイクルの責任。たとえば、様々なスマートポインタクラスは、さまざまな種類の所有権をモデル化しています(共有対ユニークなど)。 –

+6

"経験則"は、ベストプラクティスのために一般的に遵守すべきルールです。実際には、「経験則」と呼ばれるルールはありません。 – Carcigenicate

+0

@OliverCharlesworth、ありがとう。しかし、それは私の混乱のほんの一部でした:( –

答えて

2

ゼロ

ゼロのルールのルールは、メモリまたは他のオブジェクトのようないくつかのリソースを使用する必要があるクラスを作成する方法についての親指の別のルールです。この例では、文字列の文字を含む動的に割り当てられたメモリは、管理されなければならないリソースである。

特殊なクラスにリソースを管理させ、それを行うことをお勧めします。この例では、std :: stringは割り当てられたメモリの管理に関するすべての詳細を処理します。

言語と標準ライブラリが改良されたため、動的に割り当てられたオブジェクトのライフタイム(unique_ptrとshared_ptr)を管理するための機能が大幅に強化されているため、C++ 11の導入後にルールが登場しました。また、コンテナではインプレースの構築が可能になり、動的割り当ての別の理由が取り除かれました。それはおそらく、3つのもっと古い規則への更新と見なされるべきです。

ですから、以前にいくつかのメンバーを作成するためにあなたのコンストラクタで新しいを使用しているだろうとはデストラクタでを削除した場合、あなたは今、「移動の建設を取得し、メンバーの寿命を管理するためにunique_ptrをを使用して割り当てを移動する必要があります無料で"。

共有ポインタは、呼び出す正しいデストラクタを覚えることができるので、共有ポインタを介して排他的に管理されているオブジェクトは、ポリモーフィックに使用されていても不要になります。

基本的に、初期化、移動、コピー、および破棄に必要なすべてのアクションを実行するためにメンバーに依存できるクラスは、特別なメンバー関数のいずれも宣言するべきではありません。

C++のものと同じように、常にファイブ

のルールは常にその単純ではありません。

Scott Meyersが指摘しているように、何らかの理由でデストラクタを追加する必要がある場合、コンパイラがそれらを生成することができたとしても、ムーブコンストラクタと移動代入演算子は暗黙的に生成されません。

次に、コンパイラはあなたのクラスを移動するのではなく、あなたが期待するものではない場所にコピーします。これは、例えば、より多くのコピーを実行する必要があるため、プログラムの速度を遅くすることがあります。コンパイラはデフォルトでこれについて警告しません。

したがって、無関係の変更による驚きを避けるために、5つの特別な方法のうちのどれを明示的に指定することをお勧めします。彼は依然として、非リソース管理クラスを書くことを勧めます。これにより、コンパイラによって生成されたデフォルトが使用できるようになります。