73

タイトルを参照してください。

私は持っています:

class Foo {
   private:
     Foo();
   public:
     static Foo* create();
}

Fooをコピーできないようにするには、ここから何をする必要がありますか?

ありがとう!

4

10 に答える 10

19
#include <boost/utility.hpp>
class Foo : boost::noncopyable {...

しかし、スコット・マイヤーズがかつて言ったように...「それは素晴らしいクラスです、それは私が名前を少し不自然だと思っただけです、間違って自然ではありません」、またはそのようなもの。

于 2010-01-31T23:04:51.660 に答える
19

= deleteC++11 では、宣言の後に配置することで、デフォルトのコピーおよび代入コンストラクターの作成を明示的に無効にすることができます。

ウィキペディアから:

struct NonCopyable {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable & operator=(const NonCopyable&) = delete;
};

もちろん授業も同じです。

于 2012-11-29T15:16:45.117 に答える
18

コピー コンストラクターを禁止するもう 1 つの方法として、便宜上、DISALLOW_COPY_AND_ASSIGN マクロを使用できます。

// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  TypeName(const TypeName&) = delete;      \
  void operator=(const TypeName&) = delete

次に、クラス Foo で:

class Foo {
 public:
  Foo(int f);
  ~Foo();

 private:
  DISALLOW_COPY_AND_ASSIGN(Foo);
};

グーグルスタイルシートから参照

于 2010-02-01T08:31:21.920 に答える
17

そこに少し付け加えます。

前述のように、伝統的な解決策は、 と の両方をとして宣言し、それらを定義しないことです。Copy ConstructorAssignment Operatorprivate

  • それらは であるため、クラスのプライベート部分にアクセスできないそれらを使用しようとするとprivateコンパイル時エラーが発生します...
  • リンク時(そこにあるものをチェックする場合) またはおそらく実行時(ライブラリをロードしようとするとき) のundefined symbolいずれかでエラーが発生するフレンド (およびクラス自体) が残ります。

もちろん、2 番目のケースでは、エラーが発生したファイルと行がわからないため、自分でコードを確認する必要があるため、かなり面倒です。幸いなことに、それはクラス メソッドと友人​​に限定されています。


また、これらのプロパティは継承と構成の道をたどって推移的であることに注意してください。コンパイラは、 、 、および のデフォルト バージョンのみを生成しますDefault Constructor(Copy Constructor可能であればAssignment Operator) Destructor

これは、これら 4 つのいずれについても、クラスのすべてのベースと属性にアクセスできる場合にのみ自動的に生成されることを意味します。

// What does boost::noncopyable looks like >
class Uncopyable {
public:
  Uncopyable() {}

private:
  Uncopyable(const Uncopyable&);
  Uncopyable& operator=(const Uncopyable&);
};

これが、このクラスから継承する (または属性として使用する) と、これらの演算子を自分で定義しない限り、独自のクラスがコピー可能または割り当て可能になるのを効果的に防ぐ理由です。

一般に、2 つの理由から、構成よりも継承が選択されます。

  • Uncopyableポリモーフィズムがそれほど役に立たなくても、オブジェクトは効果的に
  • EBO継承はorにつながりEmpty Base Optimizationますが、属性はアドレス可能であるため、実際には必要ない場合でも (クラスの各インスタンスで) メモリを占有しますが、コンパイラは基本クラスにこのオーバーヘッドを追加しない可能性があります。

別の方法として、演算子をプライベートに宣言し、独自のクラスで定義しないこともできますが、コードの自己文書化は少なくなり、このプロパティを持つクラスを自動的に検索することはできません (本格的なパーサー)。

これがメカニズムに光を当てることを願っています。

于 2010-02-01T08:17:03.387 に答える
4

C++11 での適切な方法は、コピー コンストラクターと代入をパブリックに削除されたものとして宣言することです。非公開ではなく公開で削除: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete

于 2018-08-21T15:35:27.483 に答える
3

コピーコンストラクターをプライベートにします。

Foo(const Foo& src);

実装する必要はありません。ヘッダーファイルで宣言するだけです。

于 2010-01-31T23:00:40.063 に答える
2

これは私が使用するものです:

/* Utility classes */

struct NoCopy
{
public:
    NoCopy() {}
private:
    NoCopy(const NoCopy &);
};

struct NoAssign
{
private:
    NoAssign &operator=(const NoAssign &);
};

struct NonInstantiable
{
private:
    NonInstantiable();
};

struct NoCopyAssign : NoCopy, NoAssign
{
};
typedef NoCopyAssign NoAssignCopy;

あなたの場合:

struct Example : NoCopy
{
};
于 2010-02-01T08:24:01.733 に答える