为什么在赋值运算符重载中返回引用
Why a reference is returned in an assignment operator overload?
我读到,引用是从重载赋值运算符返回的,以启用运算符链接。但是,如果没有这种回报,运算符链似乎也有效。
有人可以对此有所了解吗?
class A
{
public:
int x,y;
char* str;
//Default Constructor
A(){}
//Constructor
A(int a, int b, char* s){
cout<<"initialisingn";
x = a;
y = b;
str = new char[10];
str = s;
}
//Destructor
~A(){}
//Overloaded assignment operator
const A& operator=(const A& obj)
{
cout<<"Invoking Assignment Operatorn";
x = obj.x;
y = obj.y;
str = new char[10];
str = obj.str;
//return *this;
}
};
ostream& operator<<(ostream& os, const A& obj)
{
os <<"X="<< obj.x<<" Y="<<obj.y<<" Str="<<obj.str<<"n";
return os;
}
int main()
{
A c(3,4,"Object C");
cout<<c;
A d, e, f;
d = e = f = c; //Assignment operator invoked 3 times
cout<<e;
}
输出:
initialising
X=3 Y=4 Str=Object C
Invoking Assignment Operator
Invoking Assignment Operator
Invoking Assignment Operator
X=3 Y=4 Str=Object C
您遇到了未定义的行为,因为operator =
期望返回的类型是const A&
,并且您没有返回任何内容。
只是不吉利,它对你有用。(是的,不走运,因为看似有效的未定义行为是最糟糕的(
我在 MSVS 中收到编译错误,ideone.com 遇到运行时错误。
http://ideone.com/xTDb6
此规则源自如下代码:
struct Foo {
Foo& copy(const Foo& x) {
return (*this = x);
}
};
当时,C++有两点不同:
- 编译器生成的运算符 = 默认返回一个右值,并且
- 编译器允许非常量引用绑定到临时引用。
上面的代码旨在等效于:
*this = x;
return *this;
但是,事实并非如此 - 由于operator=
返回了一个右值,编译器生成了一个临时值来保存赋值的结果,然后由于该函数返回了一个引用,它返回了对该临时值的引用。然后,当然,事情进展得很糟糕,因为你现在有一个悬而未决的引用,指的是一个临时的,它在创建它的完整表达式结束时被销毁了。简而言之,返回对局部引用的类情况 - 除了需要相当多的分析才能意识到本地正在生成,更不用说对它被返回的引用了。
如果您将operator=
定义为返回值而不是引用,则必须生成一个临时值,就像编译器在上面的代码中所做的那样。我还没有详细考虑其余部分,以确定当前语言的其他更改是否足以在这种情况下保护你,但我的第一反应是,你距离重建那个古老的错误已经走了一半,所以除非你在这件事上别无选择,否则我会远离。
相关文章:
- 寿命延长从函数返回引用
- 了解C++如何返回引用并绑定到引用
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 从类返回引用向量
- 使用unique_ptr并返回引用,或者我应该使用shared_ptr并在需要时制作副本
- 混淆C++从函数返回引用
- 两个相同的重载运算符[]一个返回引用
- 为什么向量的.at()成员函数返回引用而不是迭代器
- C++使用和返回引用
- 返回 T 引用的 Const 函子禁止赋值
- 返回引用是否也会延长其生存期?
- 如何返回引用,然后递增迭代器
- 如果使用返回引用的函数初始化"auto"var,为什么它不声明引用类型?
- 我是否需要将 ref 与 make_pair 一起使用才能返回引用?
- 在 vector::at 返回引用后进行更改
- 为什么PyImport_ImportModule返回引用计数为 3 而不是 1 的 PyObject*
- 超出返回引用的单一实例生存期
- Boost.Python 返回引用现有 c++ 对象的 python 对象
- C++ 运算符 += 重载返回引用
- 如何声明接受转发引用并返回引用或副本的函数模板