【问题标题】:Return result by reference in C++在 C++ 中通过引用返回结果
【发布时间】:2018-09-09 23:39:52
【问题描述】:

我正在用 C++ 练习一些东西,我遇到了一个我可以解决的任务,但我对下面的这段代码很好奇。我不知道为什么我们在这两个函数中通过引用返回我们的值:

fraction& operator+=(fraction);
fraction& operator++();

#include <iostream>
using namespace std;

class fraction
{
private:
    int br;
    int im;
public:
    fraction(int=0,int=1);
    fraction& operator+=(fraction);
    fraction& operator++();
    fraction operator++(int);
    void print(){cout<<br<<"/"<<im<<endl;}
};

fraction::fraction(int a,int b):br(a),im(b){}

fraction& fraction::operator+=(fraction r)
{
    br = br*r.im + im*r.br;
    im = im*r.im;
    return *this;
}

fraction& fraction::operator++()
{
    return (*this)+=1;
}

fraction fraction::operator++(int i)
{
    fraction pom(*this);
    (*this)+=1;
    return pom;
}

int main()
{
    cout<<"Type in the values for fractions"<<endl;
    int b,i;
    cin>>b>>i;
    fraction r1(b,i);
    cin>>b>>i;
    fraction r2(b,i);
    r1+=(r2++);
    r1.print();
}

然后我尝试删除这些函数中的&amp;,该代码也可以正常工作:

#include <iostream>
using namespace std;

class fraction
{
private:
    int br;
    int im;
public:
    fraction(int=0,int=1);
    fraction operator+=(fraction);
    fraction operator++();
    fraction operator++(int);
    void print(){cout<<br<<"/"<<im<<endl;}
};

fraction::fraction(int a,int b):br(a),im(b){}

fraction fraction::operator+=(fraction r)
{
    br = br*r.im + im*r.br;
    im = im*r.im;
    return *this;
}

fraction fraction::operator++()
{
    return (*this)+=1;
}

fraction fraction::operator++(int i)
{
    fraction pom(*this);
    (*this)+=1;
    return pom;
}

int main()
{
    cout<<"Type in the values for fractions"<<endl;
    int b,i;
    cin>>b>>i;
    fraction r1(b,i);
    cin>>b>>i;
    fraction r2(b,i);
    r1+=(r2++);
    r1.print();
}

那么,我的问题是,为什么我们在第一个代码中使用&amp;

另外,如果您能告诉我为什么这段代码不起作用,我将不胜感激。这是上面两个代码的组合,我只从一个函数中删除了&amp;

#include <iostream>
using namespace std;

class fraction
{
private:
    int br;
    int im;
public:
    fraction(int=0,int=1);
    fraction operator+=(fraction);
    fraction& operator++();
    fraction operator++(int);
    void print(){cout<<br<<"/"<<im<<endl;}
};

fraction::fraction(int a,int b):br(a),im(b){}

fraction fraction::operator+=(fraction r)
{
    br = br*r.im + im*r.br;
    im = im*r.im;
    return *this;
}

fraction& fraction::operator++()
{
    return (*this)+=1;
}

fraction fraction::operator++(int i)
{
    fraction pom(*this);
    (*this)+=1;
    return pom;
}

int main()
{
    cout<<"Type in the values for fractions"<<endl;
    int b,i;
    cin>>b>>i;
    fraction r1(b,i);
    cin>>b>>i;
    fraction r2(b,i);
    r1+=(r2++);
    r1.print();
}

很抱歉提出了一些菜鸟问题,但我刚开始练习 C++,我花了几个小时试图弄清楚这一点。

【问题讨论】:

  • 按价值返回意味着制作不必要的副本。另外,可以写(++x) = 10 之类的东西,这很愚蠢,但它适用于int,并且重载运算符的约定是“做ints 做的事情”。
  • 这样a += b += c; 就可以了。顺便说一句,你包含了太多与问题无关的代码。
  • @DeiDei 我不认为a += b += c 需要operator+= 通过引用返回。 (a += b) += c 会。

标签: c++ reference return operator-overloading this


【解决方案1】:

那么,我的问题是,为什么我们在第一个代码中使用&amp;

&amp; 用于性能和一致性原因。 两个运算符(预增量运算符++ 和赋值运算符+=)根据他们的假设修改提供的值。例如:

int i=5;
std::cout << ++i; // This will print 6. Notice there is no more value 5, even here
std::cout << i;   // This will print 6 also.

由于丢失了原始值,因此创建新对象并销毁当前对象毫无意义。只有当前对象可以被重用以提供新的价值。

我建议在重载运算符时查看参考,因为很容易创建具有性能损失或不适用于 const 对象的自己的版本。这里有一些链接。

另外,如果您能告诉我为什么这段代码不起作用,我将不胜感激。它是上面两个代码的组合,我只从一个函数中删除了 &。

这个有点棘手。 如果您仔细查看第三个示例中的代码:

fraction fraction::operator+=(fraction r)
{
    br = br*r.im + im*r.br;
    im = im*r.im;
    return *this;
}

fraction& fraction::operator++()
{
    return (*this)+=1;
}

您会注意到operator++ 在内部使用operator+=。 事实上operator++ 正在返回operator+= 返回的内容,因此operator++ 正在返回对本地fraction 对象的引用,该对象在operator++ 结束时被销毁。你得到对刚刚被破坏的对象的引用。这很糟糕,这就是它不起作用的原因。

【讨论】:

  • 如您所知,后增量r++ 的语义很棘手,因为您必须复制然后返回原始值。但是你不想违背鸭式代码的期望。使用++r 几乎总是更有效。
猜你喜欢
  • 2014-12-11
  • 1970-01-01
  • 2020-06-18
  • 2023-03-19
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
相关资源
最近更新 更多