タイトルを参照してください。
私が持っています:
class Foo {
private:
Foo();
public:
static Foo* create();
}
Fooをコピー不可にするには、ここから何をする必要がありますか?
ありがとう!
class Foo {
private:
Foo();
Foo( const Foo& ); // non construction-copyable
Foo& operator=( const Foo& ); // non copyable
public:
static Foo* create();
}
ブーストを使用している場合、コピー不可から継承することもできます: http://www.boost.org/doc/libs/1_41_0/boost/noncopyable.hpp
編集:この機能をサポートするコンパイラがある場合、C++ 11バージョン:
class Foo {
private:
Foo();
Foo( const Foo& ) = delete; // non construction-copyable
Foo& operator=( const Foo& ) = delete; // non copyable
public:
static Foo* create();
}
コピーコンストラクタと代入演算子もプライベートにします。宣言だけで十分です。実装を提供する必要はありません。
#include <boost/utility.hpp>
class Foo : boost::noncopyable {...
しかし、スコット・マイヤーズがかつて言ったように...「それは素晴らしいクラスです、それはちょうど私が少し不名誉であると思うことです」、またはそのような何か。
コピーコンストラクタを禁止するもう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);
};
そこに少し追加します。
従来の解決策は、前述したように、Copy Constructor
とAssignment Operator
の両方をprivate
としてdeclareに、notにdefineそれら。
private
であるため、クラスのプライベート部分にアクセスできないユーザーを使用しようとすると、コンパイル時エラーが発生します。 ..undefined symbol
の形式でエラーが発生する友人(およびクラス自体)を残すそこにあるものをチェックします)、またはおそらくrun-time(ライブラリをロードしようとしたとき)。もちろん、エラーが発生したファイルと行の指示がないため、コードを自分で確認する必要があるため、2番目のケースではかなり面倒です。幸いなことに、それはクラスのメソッドと友人に限定されています。
また、これらのプロパティは継承と合成の道を推移することに注意する価値があります。コンパイラはDefault Constructor
、Copy Constructor
、Assignment Operator
、およびDestructor
のデフォルトバージョンのみを生成しますかもしれない。
これは、これらの4つのいずれについても、クラスのすべてのベースと属性にアクセスできる場合、自動的に生成されるonlyことを意味します。
// What does boost::noncopyable looks like >
class Uncopyable {
public:
Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
このため、このクラスから継承する(または属性として使用する)ことにより、自分でこれらの演算子を定義しない限り、クラスのコピーや割り当てが事実上できなくなります。
一般に、2つの理由から、構成よりも継承が選択されます。
Uncopyable
ですEBO
またはEmpty Base Optimization
につながりますが、属性はアドレス可能であるため、実際には必要ではなくても(クラスの各インスタンスで)メモリを占有しますが、コンパイラはこのオーバーヘッドを追加しない可能性があります基本クラス。または、演算子をプライベートとして宣言し、独自のクラスで定義しないこともできますが、コードはself-documentingより少なくなります。このプロパティを持つクラスを自動的に検索できるようになります(本格的なパーサーがない限り)。
これがメカニズムにいくらかの光を当てることを願っています。
C++ 11では、宣言の後に= delete
を配置することにより、デフォルトのコピーおよび割り当てコンストラクターの作成を明示的に無効にできます。
From Wikipedia :
struct NonCopyable {
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
NonCopyable & operator=(const NonCopyable&) = delete;
};
もちろん、クラスにも同じことが言えます。
C++オブジェクトをコピー不可にする一般的な方法は、コピーコンストラクターとコピー割り当て演算子を明示的に宣言し、それらを実装しないことです。これにより、コンパイラが独自に生成するのを防ぎます。 (通常、これはprivate
の宣言と組み合わせて行われるため、リンカエラーではなくコンパイルエラーが生成されます。)
boost::noncopyable
継承可能なクラス。上記で説明したことを行います。
コピーコンストラクタをプライベートにします。
Foo(const Foo& src);
実装する必要はなく、ヘッダーファイルで宣言するだけです。
これは私が使用するものです:
/* 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
{
};
C++ 11の良い習慣は、コピーコンストラクターと割り当てをパブリックに削除されたものとして宣言することです。非公開ではなく、publicly削除: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-delete