クラス構築編コピー禁止を徹底させるNoncopyableクラスクラスのオブジェクトは至る所でコピーが発生しています。これには2つの方法が使い分けられています。代入演算子によるコピーコピーには「コピーコンストラクタによるコピー」と「代入演算子によるコピー」があります。src.val;}};コピーコンストラクタを自前で書いた場合、上のように自分のメンバーのコピーを責任をもって行う必要があります。「普段コピーコンストラクタなんて書いて無いけど...」という方もいらっしゃると思います。コピーコンストラクタが明示的に書かれていない場合、コンパイラは自動的にコピーコンストラクタを作ってくれています。&src」という引数を持ったコンストラクタで、コピーはメンバ変数全部の「代入演算子」を使います。src.val;}};コピーコンストラクタと引数は全く同じで、内部で引数のオブジェクトのメンバをやはり代入演算子でコピーします。これも明示的に定義しなくてもコンパイラが上のように作ってくれます。オブジェクトコピーの禁止オブジェクトをコピーされると困る場合があります。クラスの内部でオブジェクトをnewして、デストラクタでdeleteしている場合です。val;}};コンストラクタで*valに有効なポインタを代入して、デストラクタでそれをdeleteしています。obj2;代入演算子はデフォルトでは内部でメンバ変数を単純に代入するのでした。言うことはobj1のポインタ変数valがobj2のそれで上書きされてしまいます。この段階でobj1.valはもう迷子で一生消されることは無くなってしまいます。それだけでなく、obj1のデストラクタは代入されたobj2.valのポインタを消してしまいます(obj2.valがダングリング状態)。obj2が消される直前にそのデストラクタが呼ばれた段階で、不定なポインタを消そうとするためメモリ保護違反で落ちます。1回の代入で、ここまで悲劇的なことが連鎖するんです!「MyClassのオブジェクトをコピーしないように」とお願いしても、冒頭に挙げたようにどこか知らない所でコピーは起きます。人の目で制御するのは実質不可能でしょう。そこで、機能的にコピーできないようにしてしまいます。{}};この1行を加えるだけで、先の代入演算子によるコピーが出来なくなります。=演算子(実質関数)がprivateなのでクラスの外の人が呼べないためです。obj1;これはコピーコンストラクタによる代入のため、MyClassの代入演算子が使われないためです。先程の悲惨なバグが再び発生します。{}};これでMyClassは一切の代入行為、つまりコピーができなくなります。通常、オブジェクトのコピーを禁止したい場合はコンピーコンストラクタと代入演算子の両方を上のようにprivate宣言します。一切のコピー行為を禁止することで成り立っているのが「シングルトンパターン」です。このパターンはさらにデフォルトコンストラクタまでもprivateにする徹底ぶりです。オブジェクトの生成すら禁止しているわけです。Noncopyableクラスでコピー禁止属性を付けるさて、上のようにすればコピー禁止になるのですが、毎回作るクラスにコピーコンストラクタと代入演算子をオーバーライドするのは面倒です。val;}};こうするだけでコピー禁止属性が付きます。親にするだけなのですから異常に簡単ですよね。Noncopyableクラスにはコンストラクタが必要です。これが無いと、オブジェクトの生成すら禁止されてしまいます。意図的にそういう超禁止属性を付けるのもありです。コピー禁止属性を付ける事で、上のような内部でnew、デストラクタでdeleteするタイプのクラスはかなり安全に扱う事ができるようになります。逆にコピー自体が出来なくなってしまうので、cloneメソッドのような明示的コピーを促すメソッドを追加する必要が出てきます。その場合はNoncopyable属性を付けずにコピーコンストラクタと代入演算子を適切にオーバーライドした方が扱いは楽になります。堅牢なNoncopyable上の実装について、りお様よりより堅牢な実装方法を教わりました。上のNoncopyableクラスは機能はします。Noncopyableオブジェクトを作れます。コンストラクタがpublicとして公開されているためです。これをprotectedにするとコンストラクタが非公開になるのでNoncopyableオブジェクトすら作れなくなります。次に、コピーコンストラクタと代入演算子ですが、これは宣言だけにします。「え!」と思うかもしれませんが、クラスで宣言されたメソッドは、それが実装で呼ばれなければ宣言そのものが無かった事にされます(最適化の一貫)。逆に実装で呼ばれた時に「そのメソッドの実体はないぜ!」とコンパイラに怒られます。val;}};こうするとコンパイラの最適化が促進されるとの事です。奥深いもんです(-_-;。