オブジェクトを初期化できるが割り当てられないクラスを作成する必要があります。
代入演算子を定義しないことでこれを実行できるのではないかと思いましたが、コンパイラーはコンストラクターを使用して代入を行います。
このようにする必要があります:
Object a=1; // OK
a=1; // Error
どうすればできますか?
削除 代入演算子:
_#include <iostream>
using namespace std;
struct Object
{
Object(int) {}
Object& operator=(int) = delete;
};
int main()
{
Object a=1; // OK
a=1; // Error
}
_
代替ソリューション
explicit キーワードを使用できます。
_#include <iostream>
using namespace std;
struct Object
{
explicit Object(int) {}
};
int main()
{
Object a(1); // OK - Uses explicit constructor
a=1; // Error
}
_
更新
コメントでuser2079303が述べたように:
代替ソリューションは
a=Object(1)
のような通常のコピー/移動割り当てを妨げないことに言及する価値があるかもしれません
これは以下を使用することで回避できます:Object& operator=(const Object&) = delete;
a
constにすることでトリックが行われます
const Object a=1; // OK
これで、a
がa
として宣言されているため、const
に値を割り当てることができなくなります。 a
をconst
として宣言する場合、宣言時にa
を初期化する必要があることに注意してください。
a
をconst
として宣言し、初期化すると、a
に他の値を割り当てることができなくなります。
a=1; //error
これが代入演算子を定義しないことによってそうなることを望みました
コピー代入演算子(_const Object&
_をパラメーターとして取る)が暗黙的に生成されるため、これは機能しません。また、_a = 1
_を記述すると、生成されたコピー代入演算子が呼び出され、_1
_が変換コンストラクターObject::Object(int)
を介してObject
に暗黙的に変換されます。次に_a = 1;
_は正常に動作します。
代入演算子は、int
を deleted として明示的に宣言できます(C++ 11以降)。これは、多重定義解決でコピー割り当て演算子の前に選択されます。
関数がオーバーロードされている場合、オーバーロードの解決が最初に行われ、削除された関数が選択された場合にのみプログラムが不正な形式になります。
例えば.
_struct Object {
Object(int) {}
Object& operator=(int) = delete;
};
_
副作用のある他の解決策もあります。 Object::Object(int)
をexplicit
として宣言して、int
からObject
への暗黙的な変換を禁止し、_a = 1
_を失敗させることができます。ただし、コピーの初期化ではexplicit
コンストラクタが考慮されないため、これにより_Object a = 1;
_も失敗することに注意してください。または、コピー割り当て演算子を削除済みとしてマークすることもできますが、これによりObject
s間の割り当ても失敗します。
どうすればできますか?
コンストラクタを作るexplicit
struct Object
{
explicit Object(int in) {}
};
delete
代入演算子。
struct Object
{
Object(int in) {}
Object& operator=(int in) = delete;
};
上記の両方のオプションを使用できます。
struct Object
{
explicit Object(int in) {}
Object& operator=(int in) = delete;
};
初期化後に割り当てが必要ない場合は、delete
を引数の型として使用して、代入演算子をObject
できます。
struct Object
{
explicit Object(int in) {}
Object& operator=(Object const& in) = delete;
};
それは次の使用を防ぎます:
Object a(1);
a = Object(2); // Error
a = 2; // Error
削除された関数はC++ 11以降でのみ使用できます。古いコンパイラの場合、代入演算子private
を作成できます。
struct Object
{
Object(int) {}
private:
Object& operator=(int);
};
コンパイラはエラーをスローします
Object a=1; //ok
a=2; // error
しかし、あなたはまだ行うことができます
Object a=1,b=2;
b=a;
デフォルトの代入演算子がコンパイラーによって生成されるのを妨げられないためです。したがって、デフォルトの割り当てprivate
をマークすると、この問題が解決します。
struct Object
{
Object(int) {}
private:
Object& operator=(Object&);
};