no-image

【C++】自動定義されるものとコピー禁止方法について ~コンストラクタ、デストラクタ、代入演算子~

自動定義と手動定義

自分で定義していない場合

この場合、

  1. デフォルトコンストラクタ
  2. コピーコンストラクタ
  3. デストラクタ
  4. コピー代入演算子

が自動で定義されます。

自動定義で、コピー関係(コピーコンストラクタ、コピー代入演算子)は、クラスのメンバ変数を全てコピーしてくれています。自分で定義するときは、この点に注意しましょう。

自分で定義した場合

1~4の内、自分で定義した部分は、自動で定義されません。

注)引数付きコンストラクタを定義するとデフォルトコンストラクタは自動で定義されません

コピー禁止

例として、シリアルコードは一つ限りでコピーの必要はないとします。余計なミスを起こさないためにもコピーを禁止したい。

これを解決するのが、先ほどの手動定義です。コピー関係(コピーコンストラクタ、コピー代入演算子)をpublicではなくprivateで宣言すればいいのです。

“private” で “宣言” の意味

アクセスエラーとリンクエラーの2重エラーでコピーできなくしています。

private

9行、10行目にクラス外で呼び出しているのでアクセスエラーがでます。

定義ではなく宣言

定義していない(関数の後に{}を付ていない)場合を宣言といいます。宣言しただけの関数を呼び出すとリンクエラーがでるので、privateの条件をクリア(たとえば、クラス内でコピーしようと)したとしても、事実上呼び出すことが不可能になります。

リンクエラーをコンパイルエラーに

リンクエラーは実行するまでエラーを吐いてくれません。

継承よって、先ほどのリンクエラーをアクセスエラーにすることができます。

おわりに

簡潔なソースコードを書くためにも自動定義で十分な場合は、それに任せましょう。

参考

「Effective C++ 第3版 5項・6項」