Gal*_*ian 29 c++ initialization variable-assignment
我需要创建一个类,其对象可以初始化但不能分配.
我想也许我可以通过不定义赋值运算符来做到这一点,但编译器使用构造函数来进行赋值.
我需要它是这样的:
Object a=1;    // OK
a=1;           // Error
我该怎么做?
You*_*saf 58
使a const成为可能
const Object a=1;    // OK
现在,你将不能够为任意值分配给a作为a被声明为const.请注意,如果您声明a为const,则必须a在声明时初始化.
一旦你已经声明a为const也初始化它,你将不能为任何其他值赋给a 
 a=1;   //error
Jon*_*nas 49
您可以删除赋值运算符:
#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;
son*_*yao 13
我希望通过不定义赋值运算符来实现这一点
这不起作用,因为const Object&隐式生成了复制赋值运算符(它作为参数).在编写时a = 1,生成的复制赋值运算符将尝试调用,并1可以Object通过转换构造函数隐式转换为Object::Object(int); 然后a = 1;工作正常.
你可以声明赋值运算符取int为删除(因为C++ 11)明确; 将在重载分配操作符之前在重载分配操作符中选择.
如果函数过载,则首先发生重载解析,如果选择了删除的函数,则程序只会格式错误.
例如
struct Object {
    Object(int) {}
    Object& operator=(int) = delete;
};
还有一些其他副作用的解决方案.你可以声明Object::Object(int)为explicit从禁止隐式转换int到Object,然后做a = 1失败.但请注意,这也会导致Object a = 1;失败,因为复制初始化不考虑explicit构造函数.或者您也可以将复制赋值运算符标记为已删除,但这会使Objects 之间的赋值也失败.
我该怎么做?
制作构造函数 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
小智 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&);
};