我有一个类,其成员不会被类的方法更改,因此我将其标记为const
。我的问题是我使用默认赋值运算符就像复制构造函数一样,以避免多个声明。但在这种情况下,赋值运算符不会自动生成,因此我得到一些编译器错误:
'operator =' function is unavailable
。这似乎没有真正的生活场景,其中可以实际使用const类成员(例如,你在STL代码中看到过任何const成员吗?)。
除了删除const
之外,有没有办法解决这个问题?
编辑:一些代码
class A
{
public :
const int size;
A(const char* str) : size(strlen(str)) {}
A() : size(0) {}
};
A create(const char* param)
{
return A(param);
}
void myMethod()
{
A a;
a = create("abcdef");
// do something
a = create("xyz");
// do something
}
答案 0 :(得分:3)
这是导致此问题的误解:
[..]没有被类
的方法改变
成员变量 由您的类(赋值运算符)的方法更改。包括由编译器合成的一个。如果将成员变量标记为const
,则表示此变量将(不应该!)在对象的生命周期内更改其值。很明显,为对象分配新值违反了此声明。因此,如果您确实不希望成员更改,请不要将其const
。
答案 1 :(得分:2)
const
成员在许多情况下都是理想的。当然,有一个明显的情况是值不应该或不能改变,但它也是优化和并发的一个重要限制 - 不是每个类型都需要或应该有赋值运算符。
如果成员需要赋值行为,则该变量不能是const
。
当值/成员不能变异或被this
变异时,为变量成员提供单独的接口(甚至更复杂情况下的子类型>组合)更清楚:
class t_text {
public:
// ...
public:
void setString(const std::string& p);
private:
const t_text_attributes d_attributes;
std::string d_string;
};
因此,我的建议是隐藏赋值运算符,并使'mutable chunk'或成员可以设置为清晰:
text.setString("TEXT"); // << Good: What you read is what happens.
text = otherText; // << Bad: Surprise - attributes don't actually change!
答案 2 :(得分:2)
您不能拥有const
成员和支持作业,至少不能
具有预期语义的赋值。从逻辑上讲,const
是一个
承诺会员永远不会改变,并且任务是
(隐含地,在大多数人的心目中)所有数据的承诺
成员将采用右侧成员的价值观
(通常意味着改变)。有一个非常明确的冲突
在这两个承诺之间。
当然,很多类型不应该支持任务开始;
对于不支持赋值的类型,声明a没有问题
数据成员const
。但总的来说,我发现const
很多
在这里不太有用; const
是合同的一部分,数据成员是
通常不是该类外部合同的一部分。 (但很多
取决于 - 如果数据成员是公共的或受保护的,那么事实
它是不可变的可能是外部合同的一部分。并且
当然,表达内部类不变量没有错
在语言结构中,要么。)
答案 3 :(得分:1)
是的,您可以覆盖赋值运算符。
因为您使用的是默认值,编译器也会尝试复制const
成员。这是非法的,因为它是const
。
class A
{
private:
const int a;
public :
A() : a(0) {}
A& operator = (const A& other) {return *this;}
};
int main()
{
A a;
A b;
a = b; //this is legal if operator = is declared
}