Jud*_*nga 10 c++ assignment-operator copy-assignment
说我想覆盖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
Run Code Online (Sandbox Code Playgroud)
然后在我的实现中operator =,我有这样的事情:
Poly& Poly::operator=(const Poly &source) {
// Skipping implementation, it already works fine…
return *this;
}
Run Code Online (Sandbox Code Playgroud)
不介意实现,它已经正常工作.
我关心的是你什么时候会发生什么return *this?我知道它返回对象的引用,但这是怎么回事?
p2 = &p1
Run Code Online (Sandbox Code Playgroud)
Pau*_*ans 16
您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
Run Code Online (Sandbox Code Playgroud)
因为该陈述基本上是:
p3.operator=(p2.operator=(p1));
Run Code Online (Sandbox Code Playgroud)
如果p2.operator=(...)没有,return *this你没有任何意义可以传递进去p3.operator=(...).
void如果您无论如何都不需要链式赋值(如其他答案中所示),则可能会试图让复制赋值运算符返回。毕竟,链式作业通常难以阅读和理解,因此不允许它们被视为一种改进。
然而,一个经常被忽视的方面是这void operator=(Poly& const)意味着您的类型将不再满足需要返回类型的CopyAssignable概念T&。
不满足该CopyAssignable概念的类型不能正式用于某些标准容器操作,例如std::vector::insert,这意味着以下看似无辜的代码段会产生未定义的行为,即使它可能运行得非常好:
#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
}
Run Code Online (Sandbox Code Playgroud)
正如 C++ 标准在 § 17.6.4.8/2.3 中解释的那样,它讨论了对使用标准库的程序的约束:
(...)在以下情况下效果未定义:
(...) 对于在实例化模板组件时用作模板参数的类型,如果对类型的操作未实现适用的需求子条款 (...)的语义。
当然,正是由于未定义的行为,编译器才被允许忽略错误并使程序表现良好,与明显预期的行为相匹配。但并不是必须这样做。
您还应该考虑到您无法预测您的Poly类型的所有未来用途。有人可能会编写一些模板函数,例如:
template <class T>
void f(T const& t)
{
T t2;
T t3 = t2 = t;
// ...
}
Run Code Online (Sandbox Code Playgroud)
此功能将不适用于您的Poly班级。
只要不要违反这个 C++ 约定,你就不会遇到麻烦。
p2 = p1是一个简写p2.operator=(p1).它只是调用你的operator=函数,它返回一个引用p2,然后你忽略它.为了说明这一点,让我们把它assign代替operator=:
Poly& Poly::assign(const Poly &source) {
.
.
.
return *this;
}
Run Code Online (Sandbox Code Playgroud)
而不是p2 = p1,你会写
p2.assign(p1);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,调用的结果将assign被忽略,但您不必忽略它.例如,你可以写:
p3.assign(p2.assign(p1));
Run Code Online (Sandbox Code Playgroud)
使用operator=而不是assign,这变成了
p3 = (p2 = p1);
Run Code Online (Sandbox Code Playgroud)
但由于赋值是右关联的,因此也可以写成
p3 = p2 = p1;
Run Code Online (Sandbox Code Playgroud)
这种能够一次完成多个赋值的形式最初来自C,并且通过返回的约定保存在C++ *this中operator=().
| 归档时间: |
|
| 查看次数: |
2117 次 |
| 最近记录: |