【问题标题】:c++ : Whats difference in "catching reference in value" vs "catching value in value" during function return?c ++:在函数返回期间“捕获值中的引用”与“捕获值中的值”有什么区别?
【发布时间】:2018-03-13 03:56:01
【问题描述】:

当我们通过返回引用分配时,内部 1 和 2 究竟发生了什么?

Class A
{
    A& operator= (const A &ax)
    {
        return *this;
    }
}
int main()
{
    A a;
    A b;
    b = a; // -------------- 1
    A c = a;  // ----------- 2
}

// ---------------------------------------------------------------

下面会发生什么不同(赋值返回值)? :

Class A
{
    A operator= (const A &ax)
    {
        return *this;
    }
}
int main()
{
    A a;
    A b;
    b = a; // -------------- 3
    A c = a;  // ----------- 4
}

【问题讨论】:

  • 我知道赋值和初始化。但是以上两个示例的内部执行步骤有什么区别呢?
  • @KoolWagh 第 1 步正在调用 b.operator=(a);。但是因为第 2 步是初始化,而不是赋值,所以它根本不调用您的 operator=,而是调用复制构造函数。 A c = a; 只是 A c(a); 的语法糖
  • @RemyLebeau 但是在第一个代码中从赋值返回时,返回了引用;而 b 不是参考。它是如何收集在其中的?在第二种情况下,赋值返回值,b 是值。您将如何解释两个案例之间的内部差异?
  • @KoolWagh 你没有抓住重点。 A::operator= 的返回值是无关,因为您的代码根本没有将它用于任何事情。调用b = a; 与调用b.operator=(a); 相同,忽略返回值。所以无论它返回一个引用还是一个值,都没有关系。调用A c = a; 与调用A c(a); 相同,所以根本不调用A::operator=,而是调用A::A(const A&),所以同样,A::operator= 的返回值根本不重要
  • 差异仅在 c = b = a (c.operator=(b.operator(a))) 等表达式中可见。试试你的operator=(第 1 步和第 3 步),你会看到。

标签: c++ c++11 operator-overloading return-by-reference return-by-value


【解决方案1】:

还有一个主要错误,因为operator= 被设为私有并且代码格式不正确,但这可以通过添加public: 访问修饰符来纠正。

operator= 是从存储到b 变量的对象中调用的,因此这种赋值变体根本不应该执行赋值。

#include <iostream>

class A
{
public:
    float a1;

    A& operator= (const A &ax)
    {
        return *this;
    }
};

int main()
{
    A a; 
    a.a1 = 3;

    A b; 
    b.a1 = 5;

    b = a; // -------------- 1

    std::cout << b.a1; // outputs 5

    A c = a;
    std::cout << c.a1; // outputs 3

}

线

A c = a;

称为初始化,不使用operator=,而是使用(由编译器生成)复制构造函数,它对对象进行浅拷贝。

您的错误是成员 operator= 旨在将其参数的值分配给 thisoperator=返回赋值结果,可用于链接:a=b=c;

A& A::operator= (const A &right)

等价于

A& operator= (A &left, const A &right)

【讨论】:

  • C++中没有深拷贝和浅拷贝的概念。副本就是副本。它是复制构造函数和赋值运算符所说的任何内容。两者需要保持一致。当我们在八十年代中期对此感到困惑时,我们在第一次 C++ 会议上决定默认的复制构造函数将复制对象的每个组件,以此类推。有人可能会说,“那很深。” :-)
  • @JiveDadson 浅\深拷贝是语义概念,而不是语言概念。 c++ 本身只做一个浅拷贝。对象的浅拷贝复制所有成员字段值。深拷贝复制所有拥有的资源。有些语言总是做深拷贝,有些只做浅拷贝,比如 C 或 C++。
  • 我知道 Java 和 Python 人如何使用这些术语。我是一个 C++ 人。复制?
  • @JiveDadson 逐位解释无效,因为对象可能没有标准布局(C 兼容)。 Fred Swartz 和 Bjarne Stroustrup 使用这些术语,这与 C++ 人一样。以及研究所的几乎所有讲师这是解释为什么编译器生成的复制构造函数不够的基本术语。我从来没有接触过 Java,我想这个词来自 Ada。
  • 嗯,是的,逐位是错误的。那里没有争论。和平。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
相关资源
最近更新 更多