考虑我有一个类型的对象,B
其中包含一个类型的对象A
。并A
包含一个无法更改的整数。FromB
A
由非常量引用返回(因为它包含一些有用的方法):
class A {
private:
int i;
public:
A(int i) : i(i) {};
void doSomethingNonConst() {}
int getInt() {
return i;
}
}
class B {
public:
A& getA();
}
但是有一个问题:我可以执行以下操作:getA() = A(5);
这当然会更改无法更改的整数。我的解决方案是做一些事情operator=
,即仅在目标和源的整数相等时复制,否则抛出异常:
A& operator=(const A& a) {
if (a.i == i) {
//do copy
} else
//throw an exception
}
这是好的设计解决方案吗?如果不是,那么我怎样才能做得更好?也许,最好复制所有内容,但在外部代码中添加一些整数相等性检查?
虽然您可以这样做,但它可能会使人们感到困惑,并且您必须在运行时处理它。通常更希望在编译时出现错误并完全防止“复制”。
在这种情况下,您可以创建 integer const
,这将阻止隐式默认复制运算符。
class A {
private:
const int i;
public:
A(int i) : i(i) {};
void doSomethingNonConst() {}
int getInt() {
return i;
}
};
class B {
public:
B() : a(5) {}
A &getA() { return a; } // still non-const here
private:
A a;
};
int main()
{
B b;
A otherA(60);
// Compile error. GCC: use of deleted function 'A& A::operator=(const A&)'
// 'A& A::operator=(const A&)' is implicitly deleted because the default definition would be ill-formed
b.getA() = otherA;
}
否则,您可以明确地摆脱运算符,例如,如果由于其他原因无法将变量设置为 const。在某些情况下,也可能需要通过复制构造函数来防止复制,其工作方式相同。
您可以通过删除默认运算符来做到这一点A &operator = (const A &) = delete;
。
class A {
private:
int i;
public:
A(int i) : i(i) {};
A (const A &) = delete;
A &operator = (const A &) = delete;
void doSomethingNonConst() {}
int getInt() {
return i;
}
};
int main()
{
B b;
A otherA(60);
b.getA() = otherA; // Compile error. GCC: use of deleted function 'A& A::operator=(const A&)'
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句