#6 コンパイラが自動生成する関数を使用禁止する方法

ということで,Effective C++6項のお話です.

コンパイラが自動で生成する関数

クラスを自作した時,明示的に自作関数を書かなければ下記の関数はコンパイラが自動生成するのでした.

1.コンストラクタ    (Hoge())
2.デストラクタ     (~Hoge())
3.コピーコンストラクタ (Hoge(const Hoge& obj))
4.コピー代入演算子   (Hoge& operator=(const Hoge& obj))

で,自作するクラスの種類によってはコピーや代入をさせたくないものもあると思います.この場合には,クラスのユーザにそのことを気づいてもらわなければいけません.今回はこのお話です.

コンパイラが自動生成する関数を禁止する方法

ということで,「自作しなければコンパイラが自動で生成してしまう.」というおはなしだったので,自分で作ってコンパイラを黙らせます.で,自作関数をpriavateスコープにしておけば,それらの関数がユーザから使えなくなります.例えば,コピーコンストラクタ・コピー代入演算子の使用を禁止したいとします.この時は下記のように「privateスコープに関数宣言をして,定義を書かない」という対応を取ればOKです.

下記の例では,コピーコンストラクタ・コピー代入演算子は「無事?」コンパイルエラーになります.

#include <iostream>
#include <string>
#include <vector>

class UnCopyableClass {
public:

  // コンストラクタは必要なので,宣言&定義を書く.
  UnCopyableClass() {};

  // デストラクタは必要なので,宣言&定義を書く.
  ~UnCopyableClass() {};

private:
  // コピーコンストラクタは使わせないようにしたいので,宣言だけにして,praivteスコープとする.
  UnCopyableClass(const UnCopyableClass& obj);

  // 代入演算子は使わせないようにしたいので,宣言だけにして,praivteスコープとする.
  UnCopyableClass& operator=(const UnCopyableClass &obj);
};

int main(int, char**)
{
  UnCopyableClass objA, objB;

  // コンパイルエラー! コピーコンストラクタのコールはダメ!
  //UnCopyableClass objC(objA);

  // コンパイルエラー! コピー代入演算子のコールはダメ!
  //objA = objB;

  return 0;
}

ちなみに,継承関係を使ってコピーコンストラクタ・コピー代入演算子のコールを禁止することもできます.


#include <iostream>
#include <string>
#include <vector>

class Uncopyable {
public:
  Uncopyable() {}
  ~Uncopyable() {}
private:
  Uncopyable(const Uncopyable& obj);
  Uncopyable& operator=(const Uncopyable& obj);
};

class ChildUncopyable : private Uncopyable {
public:
};

int main(int, char**)
{
  
  ChildUncopyable objA, objB;

  // コンパイルエラー! コピーコンストラクタのコールはダメ!
  // ChildUncopyable objC(objA);

  // コンパイルエラー! コピー代入演算子のコールはダメ!
  // objA = objB;

  return 0;
}