在对类对象的赋值进行链接时获取垃圾值,使用按值返回类对象的赋值运算符重载
Getting garbage value while doing chaining of assignment of class objects, using assignment operator overloading which returns class object by value
在赋值运算符重载中,如果我通过引用返回对象,如下所示
One& operator=( const One& obj).
然后程序工作正常。
但是,如果我按值返回时,如下所示
One operator=( const One& obj)
然后 o1 得到垃圾值。谁能解释为什么按值返回在赋值运算符重载中不起作用?
class One
{
public:
One(int a1, int b1) {
a = a1; b = b1;
}
int a;
int b;
One operator=( const One& obj) {
cout<<"nOperator= is calledn"; a = obj.a; b = obj.b;
}
};
int main()
{
One o1(5,5);
One o2(10,10);
One o3(15,15);
cout << "no1.a=" << o1.a << ", o1.b=" << o1.b << endl;
o1 = o2 = o3;
cout << "no1.a=" <<o1.a << ", o1.b=" << o1.b << endl;
cout << "no2.a=" <<o2.a << ", o2.b=" << o2.b << endl;
cout << "no3.a=" <<o3.a << ", o3.b=" << o3.b << endl;
return 0;
}
输出:
o1.a=-13360, o1.b=0
o2.a=15, o2.b=15
o3.a=15, o3.b=15
为什么 o1 对象在赋值运算符中按值返回的情况下显示垃圾值。通过引用返回时工作正常。为什么?
o1 = o2 = o3;
被评估为o1 = (o2 = o3);
这需要o2 = o3
返回一些东西,o1
设置为该值。但是您的过载目前没有。(形式上这意味着代码的行为是未定义的(。如果重写为
One& operator=(const One& obj)
{
std::cout << "nOperator= is calledn";
a = obj.a;
b = obj.b;
return *this; // i.e. return a reference to self.
}
那么一切都会好起来的。也就是说,很酷的猫会使用
One& operator=(One obj/*pass by value to exploit compiler optimisations*/)
{
std::cout << "nOperator= is calledn";
std::swap(*this, obj);
return *this;
}
参考:什么是复制和交换成语?
=
运算符的代码应该是这样的:
One & operator=(const One& obj)
{
cout << "nOperator= is calledn";
a = obj.a;
b = obj.b;
return *this;
}
One operator=( const One& obj)
{ cout<<"nOperator= is calledn"; a = obj.a; b = obj.b; }
函数定义中没有任何返回表达式,从而导致未定义的行为。这就是为什么操作员不能正常工作的原因。
如果您使用的是gcc
编译器,我建议您启用-Wall
选项,这将产生警告,指示失败。如果您使用的是不同的,则可能有一个等效的选项可用。
您可能还想查看复制和交换习惯用法,它提供了创建正常工作的复制分配运算符的高级见解。
相关文章:
- 为什么可以使用已删除的移动构造函数和赋值运算符移动对象?
- 为什么对象可以"moved"甚至缺少移动构造函数和移动赋值运算符?
- 复制 CTOR 与赋值运算符以初始化对象(性能)
- 具有临时对象的 Fundamenta 数据类型赋值运算符
- 为什么参数可以在对象初始化时通过赋值运算符传递给构造函数?
- C++ 指针赋值运算符重载(不仅是对象赋值,还有指针赋值)
- 使用赋值运算符功能按距离对数组对象进行排序
- 如何在没有复制赋值运算符的情况下交换两个对象
- 在对类对象的赋值进行链接时获取垃圾值,使用按值返回类对象的赋值运算符重载
- 如何重载赋值运算符以满足 ob1=ob2=ob3(ob1,ob2,ob3 是同一类的对象)
- 在其赋值运算符方法中调用对象的析构函数
- 初始化对象后,用隐式转换而不是赋值运算符调用构造函数有什么意义
- 对象的动态内存和赋值运算符重载
- 赋值运算符是否应观察赋值对象的右值?
- 初始化对象后,如何使用赋值运算符覆盖C++中的类对象
- 初始化对象时复制构造函数/赋值运算符混淆
- C++中两个/两个以上对象的重载加法赋值运算符
- 将赋值运算符绑定到 boost::function 对象
- 从初始化构造函数和赋值运算符创建的对象有什么区别
- 具有复制构造函数、简单赋值运算符和简单析构函数的动态大小的文本对象