我需要创建一个类,其对象可以初始化但不能分配。
我想也许我可以通过不定义赋值运算符来做到这一点,但编译器使用构造函数来完成赋值。
我需要这样:
Object a=1; // OK
a=1; // Error
我该怎么做?
答案 0 :(得分:58)
制作const Object a=1; // OK
const 可以解决问题
a
现在,由于a
被声明为const
,您将无法为a
分配任何值。请注意,如果您将const
声明为a
,则必须在声明时初始化a
。
将const
声明为a
并初始化后,您将无法将任何其他值分配给 a=1; //error
addItems
答案 1 :(得分:49)
您可以delete分配运算符:
#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
}
<强>更新强>
正如用户2079303在评论中提到的那样:
值得一提的是,替代解决方案不会阻止常规复制/移动分配,例如
a=Object(1)
使用以下内容可以避免这种情况:Object& operator=(const Object&) = delete;
答案 2 :(得分:13)
我希望通过不定义赋值运算符
来实现这一点
这不起作用,因为隐式生成了复制赋值运算符(以const Object&
作为参数)。当您编写a = 1
时,将尝试调用生成的复制赋值运算符,并且1
可以通过转换构造函数Object
隐式转换为Object::Object(int)
;然后a = 1;
工作正常。
您可以声明赋值运算符明确地将int
作为deleted(从C ++ 11开始);将在重载分配操作符之前在重载分配操作符中选择。
如果函数超载,则首先进行重载解析,如果选择了删除的函数,则程序只会格式错误。
e.g。
struct Object {
Object(int) {}
Object& operator=(int) = delete;
};
还有一些其他副作用的解决方案。您可以将Object::Object(int)
声明为explicit
,以禁止从int
到Object
的隐式转换,然后使a = 1
失败。但请注意,这会使Object a = 1;
失败,因为复制初始化并不考虑explicit
构造函数。或者您也可以删除复制赋值运算符,但这会使Object
之间的赋值也失败。
答案 3 :(得分:9)
我该怎么做?
制作构造函数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
答案 4 :(得分:7)
删除的函数仅在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&);
};