说我想覆盖operator =
所以我可以做类似
Poly p1; // an object representing a polynomial
Poly p2; // another object of the same type
p2 = p1; // assigns all the contents of p1 to p2
然后在我operator =
的实现中,我有这样的事情:
Poly& Poly::operator=(const Poly &source) {
// Skipping implementation, it already works fine…
return *this;
}
不介意实施,它已经正常工作。
我担心的是return *this
时会发生什么?我知道它返回对象的引用,但这是怎么回事?
p2 = &p1
答案 0 :(得分:14)
你return *this
所以你可以编写正常的复合C ++ =
语句,如:
Poly p1; //an object representing a polynomial
Poly p2;
Poly p2;
// ...
p3 = p2 = p1; //assigns all the contents of p1 to p2 and then to p3
因为该陈述基本上是:
p3.operator=(p2.operator=(p1));
如果p2.operator=(...)
没有return *this
你没有任何意义可以转入p3.operator=(...)
。
答案 1 :(得分:5)
p2 = p1
是p2.operator=(p1)
的简写。它只是调用你的operator=
函数,它返回对p2
的引用,然后你忽略它。为清楚起见,我们将其称为assign
而不是operator=
:
Poly& Poly::assign(const Poly &source) {
.
.
.
return *this;
}
现在代替p2 = p1
,你会写
p2.assign(p1);
在这种情况下,调用assign
的结果将被忽略,但您不必忽略它。例如,您可以写:
p3.assign(p2.assign(p1));
使用operator=
代替assign
,这就变成了
p3 = (p2 = p1);
但由于赋值是右关联的,因此也可以写为
p3 = p2 = p1;
这种能够一次完成多项作业的形式最初来自C,并通过在*this
中返回operator=()
的惯例保存在C ++中。
答案 2 :(得分:4)
如果您不需要链接赋值(如其他答案所示),可能会想让复制赋值运算符返回$stmt = $conn->prepare("select * from locations");
$stmt->execute();
$result = $stmt->fetchAll();
if ($result) {
echo json_encode($result);
}
。毕竟,链式作业通常难以阅读和理解,因此不允许将它们视为改进。
然而,一个经常被忽视的方面是void
意味着您的类型不再支持CopyAssignable
concept,这需要void operator=(Poly& const)
返回类型。
不符合T&
概念的类型无法正式用于某些标准容器操作,例如CopyAssignable
,这意味着以下看似无辜的代码会产生不确定的行为,甚至虽然它可能运行得很好:
std::vector::insert
正如C ++标准在第17.6.4.8/2.3节中解释的那样,它讨论了使用标准库对程序的约束:
(...)在以下情况下效果未定义:
(...)用于实例化a时用作模板参数的类型 模板组件,如果类型上的操作没有实现 适用要求的语义子条款(...)。
当然,正是因为未定义行为的,允许编译器忽略错误并使程序运行良好,与明显预期的行为相匹配。但并不要求这样做。
您还应该考虑到无法预测#include <vector>
struct Poly
{
void operator=(Poly const&) {} // Poly is not CopyAssignable
};
int main()
{
std::vector<Poly> v;
Poly p;
v.insert(v.begin(), p); // undefined behaviour
}
类型的所有未来用途。有人可能会写一些模板函数,例如:
Poly
此功能不适用于您的template <class T>
void f(T const& t)
{
T t2;
T t3 = t2 = t;
// ...
}
课程。
只是不要违反这个C ++约定,你就不会遇到麻烦。
答案 3 :(得分:2)
当你返回* this时会发生什么?
在您的示例(p2 = p1;
)中,没有。该方法将p1
复制到p2
并返回对'this'对象的引用,调用代码不使用该对象。
在p3 = p2 = p1;
等代码中,第一次调用为p2 = p1
,将p1
复制到p2
并返回对p2
的引用。然后,调用代码从该引用复制到 - p2
到p3
(并忽略对返回的p3
的引用。)
(顺便说一句:你的单元测试是否确保p1 = p1
正常工作?很容易忘记这种情况!)
答案 4 :(得分:0)
返回对目标对象的引用允许赋值链接(级联),并且类中的重载运算符遵循右关联(单击here以获取详细的运算符重载规则)
Poly a, b, c;
a = b = c;