【问题标题】:Returning objects by reference通过引用返回对象
【发布时间】:2016-06-16 13:25:00
【问题描述】:
#include<iostream>
using namespace std;
class my_class
{
    int m,n;
public:
    void show(void);
    my_class& test(my_class b)
    {
        static my_class c;
        c.m=m+b.m;
        c.n=n+b.n;
        return c;
    }
    my_class(int x,int y) //Parametrized constructor
    {
        m=x;n=y;
    }
    my_class(){} //Default consructor
};
void my_class::show(void)
{
    cout<<m<<" "<<n;
}
main()
{
    my_class a(2,3),b(3,4); //Object initialisation
    my_class d=a.test(b);
    d.show();
}

函数test 返回对函数中定义的静态对象c 的引用。我得到的输出为5 7。我需要有关以下方面的帮助:

  • 我也可以通过返回my_class而不是my_class&amp;来实现相同的输出。这里按值返回与按引用返回相比如何?在赋值语句my_class d=a.test(b)中将返回引用的数据成员复制到对象d?还是d 只是返回引用的别名?
  • 如果我将赋值语句更改为my_class&amp; d=a.test(b), 即使那样我得到相同的输出。这是否意味着两种方式 上面的说法写对了吗?

  • 您能否解释一下这两种类型的具体情况? 赋值语句?

【问题讨论】:

  • (1) d 是从test 的返回值引用的对象复制构造的(换句话说,来自c)。 (2) my_class d=a.test(b); 是声明,而不是声明。那里没有任务。 (3) 如果您将其设为 my_class&amp; d=a.test(b);,那么 d 将是对 c 的引用,而不是它的副本。

标签: c++ class return-by-reference


【解决方案1】:

这里按值返回与按引用返回的比较如何?返回引用的数据成员是否在赋值语句 my_class d=a.test(b) 中复制到对象 d?

是的,d 是使用引用的对象进行复制初始化的。 (虽然,这确实不是一个赋值,也不是一个陈述)。

...或者 d 只是返回引用的别名?

不,d 不是引用,也不是引用的别名。它是一个非引用变量。

如果我将赋值语句改为my_class& d=a.test(b),即使这样我得到相同的输出?这是否意味着上述语句的两种写法都是正确的?

取决于的定义。这两个选项都不是格式错误的,但它们做不同的事情。什么是正确取决于你打算做什么。

您能否解释一下这两种赋值语句中究竟发生了什么?

  • 当您返回一个值时,会创建一个临时对象,该对象是从返回表达式复制初始化的。
  • 返回引用时,不会创建临时副本。
  • 当您从返回的临时对象复制初始化时,会创建另一个临时对象,并将隐式复制构造函数的引用参数绑定到它。
  • 从返回的引用复制初始化时,隐式复制构造函数的引用参数绑定到返回的引用所引用的对象。
  • 当您将引用绑定到返回的引用时,它会绑定到被引用的对象。

该标准允许省略一些提到的副本。

【讨论】:

    【解决方案2】:

    这里按值返回和按引用返回如何比较?

    通过返回来自test() 的引用,与按值返回相比,对象的副本少了一份;但是,这不会改变对象d 的任何内容,它无论如何都是通过复制制作的。

    返回引用的数据成员是否在赋值语句 my_class d=a.test(b) 中复制到对象 d?

    是的。 d 在这里不是引用,它是my_class 类型的变量。但这不是赋值,这是初始化,相当于使用复制构造函数:my_class d(a.test(b));

    如果我将赋值语句更改为 my_class& d=a.test(b),即使这样我得到相同的输出?这是否意味着上述两种写法都是正确的?你能解释一下这两种赋值语句到底发生了什么吗?

    您得到相同的输出,但这是完全不同的:如果您将d 定义为引用并以这种方式初始化它(my_class d=a.test(b)),它将被初始化为静态变量c。这样,对d 的任何更改也将更改ccd 实际上将引用同一个变量)。两种说法都是正确的,但使用其中一种取决于您期望的行为。

    【讨论】:

      猜你喜欢
      • 2017-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 2012-02-13
      • 2019-03-19
      • 2023-03-15
      • 2013-07-05
      相关资源
      最近更新 更多