赋值运算符重载
背景:
在EHR模块进行调试时,发现QVector3D对象进行赋值时,出现变量未赋值成功问题。
问题描述:
在进行代码调试时,发现赋值操作未成功,导致代码逻辑异常,经过分析,发现QVector3D 赋值重载函数存在问题,返回一个临时对象,从而导致赋值失败。
const QVector3D operator=(const QVector3D& in) const {
return QVector3D(in.p[0], in.p[1], in.p[2]);
}
问题解决:
重写赋值重载函数:
QVector3D& operator=(const QVector3D& in) {
if (this != &in) { // 防止自我赋值
p[0] = in.p[0];
p[1] = in.p[1];
p[2] = in.p[2];
}
return *this; // 返回当前对象的引用
}
代码测试正常:
QVector3D a(1.0f, 2.0f, 3.0f);
QVector3D b;
QVector3D c;
b = a; // b 被正确赋值
c = b = a; // 赋值链式调用成功
这样,b
和 c
都会被正确赋值,因为 operator=
返回的是对当前对象的引用,而不是一个新的对象。这样不仅符合 C++ 的语义,而且避免了不必要的性能开销和潜在的内存管理问题。
如果 operator=
返回一个新的 QVector3D
对象而不是 *this
的引用,将会导致一些问题,主要体现在以下几个方面:
-
违背了赋值运算符的语义:
-
按照惯例,赋值运算符应该返回对左值对象(即被赋值的对象)的引用。这允许赋值操作可以链式调用,例如
a = b = c;
。 -
返回一个新的对象会导致这种链式调用的行为不正确。
-
-
效率问题:
-
每次调用赋值运算符时都创建一个新的对象会引入不必要的开销。通常,赋值运算符直接修改已有对象,避免了创建和销毁临时对象的开销。
-
-
潜在的内存管理问题:
-
如果类中涉及动态内存管理,返回一个新的对象可能会导致内存泄漏或双重释放,因为赋值运算符应该直接操作已有对象,而不是创建新的对象。
-