【问题标题】:What's the difference between returning a reference and value when overloading operator=?重载operator=时返回引用和值有什么区别?
【发布时间】:2014-08-28 23:22:54
【问题描述】:

看这里:

class IntClass
{
public:
IntClass operator=(const IntClass& rhs);
IntClass();
~IntClass();
int value;

};

实施:

IntClass::IntClass()
{
}


IntClass::~IntClass()
{
}

IntClass IntClass::operator=(const IntClass& rhs)
{
    this->value = rhs.value;
    return *this;
}

如您所见,我没有返回对该类的引用。从重载 = 运算符的示例中,我看到人们返回一个引用。这是为什么呢?

这仍然按预期运行:

IntClass a, b, c, d;

a.value = 20;

b = c = d = a;

printf("%d", b.value);
printf("%d", c.value);
printf("%d", d.value);

输出:202020

p.s 我知道公众获取价值是不好的。

【问题讨论】:

  • 返回一个值会给你一个副本。
  • 并返回一个引用返回实际的数据字段。就是这样。 Google 会在 2 秒内回答这个问题。
  • 是的,但是如果我将值从 rhs 复制到实例中,这无关紧要。我唯一能想到的是,如果这是一个巨大的类,传递一个新副本会很昂贵。参考会更便宜。
  • 确实,这就是原因。另外:在异国情调的环境中,可能希望锁定共享内存页面,然后由多个线程依次修改……这是最有效的方法,就这么简单。
  • 返回引用使赋值结果成为左值(模仿内置赋值运算符)。返回副本使结果成为右值。这可能会产生有趣的后果。例如,void f(IntClass &x); IntClass x, y; f(x = y); 仅在您的 operator= 返回引用时编译。

标签: c++ operator-overloading


【解决方案1】:

首先,让赋值运算符按值返回意味着您正在制作一个额外的副本。副本可能很昂贵,编译器通常无法忽略它。如果我们假设复制赋值和复制构造的成本大致相同,那么按值返回基本上是赋值成本的两倍。

其次,如果你的赋值运算符返回一个引用,赋值表达式的结果是一个左值,它模仿了内置的赋值运算符。如果您的赋值运算符按值返回,则表达式的结果是一个右值。这可能会产生有趣的后果:

void f(IntClass &lv); 
void g(IntClass &&rv);
void g(const IntClass &clv);

IntClass x, y; 
y.value = 10;
f(x = y);  // compiles only if operator= returns IntClass & 
           // as non-const lvalue references cannot bind to a temporary
g(x = y);  // calls g(IntClass &&) if operator= returns IntClass
           // calls g(const IntClass &) if operator= returns IntClass &

【讨论】:

  • 返回引用意味着退出函数后对象必须存在,比如函数中的静态变量。
  • @ThomasMatthews 我认为这与赋值运算符无关。
猜你喜欢
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 2016-09-07
  • 2018-05-30
  • 2013-01-19
相关资源
最近更新 更多