C++ c++;从函数返回对象

C++ c++;从函数返回对象,c++,C++,下面的代码显示了一个表示复数的类。我的兴趣是理解操作符+函数。据我所知,Complex res应该在函数operator+的框架上分配。将此对象返回给调用方是否正确?此函数返回时,帧将弹出,但调用方将继续使用res。除非有比看起来更重要的事情,比如实际的返回res可能实际上是将对象从当前帧复制到调用方的帧。另一种可能是,operator+函数中的代码可能是内联的,位于main的呼叫站点上?从我对语言的有限理解来看,类中声明的函数在调用站点上默认是内联的。任何帮助都将不胜感激 #include&l

下面的代码显示了一个表示复数的类。我的兴趣是理解
操作符+
函数。据我所知,
Complex res
应该在函数
operator+
的框架上分配。将此对象返回给调用方是否正确?此函数返回时,帧将弹出,但调用方将继续使用
res
。除非有比看起来更重要的事情,比如实际的
返回res
可能实际上是将对象从当前帧复制到调用方的帧。另一种可能是,
operator+
函数中的代码可能是内联的,位于main的呼叫站点上?从我对语言的有限理解来看,类中声明的函数在调用站点上默认是内联的。任何帮助都将不胜感激

#include<iostream>
using namespace std;

class Complex {
private:
    int real, imag;
public:
    Complex(int r = 0, int i =0) {real = r; imag = i;}
    
    Complex operator+(Complex const &obj) {
        Complex res;
        res.real = real + obj.real;
        res.imag = imag + obj.imag;
        return res;
    }
    void print() { cout << real << " + i" << imag << endl; }
};

int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2; 
    c3.print();
}
将此对象返回给调用方是否正确

C++支持按引用返回和按值返回。因为您没有使用按引用返回,所以您没有将对象的引用返回给调用者。您使用的是按值返回,因此将对象的值返回给调用者。考虑:

int foo()
{
    int i = 2;
    return i;
}

这将返回值2。它不返回对象
i
。在
返回之后,
i
本身不再存在,这无关紧要,因为它的值已被用于确定返回的值。

带值传输始终使用堆栈。 当您想要返回值时,根据调用方代码的不同,复制构造函数或赋值操作符可以隐式调用并将返回值赋值给左侧的对象。(左值)

注意:

根据所使用的编译器及其设置,第一行中的复制构造可能会发生,也可能会被省略。有关这方面的全面解释,请参见:

在学习C++时尽量不要考虑框架。它是一种高级语言,框架的概念不是它的一部分。当你掌握了这门语言,并且想学习一些实际方面,例如性能时,理解这一点可能很重要,但在这个级别上,这只会让你感到困惑。你正在从操作符+()函数返回复数值。因此,这将是res.@DS_London的副本,非常感谢!我来自Java背景,我不能超越参考文献进行思考。我用以下内容修改了上面的代码:在
operator+
I中添加了以下行
cout-Np。您可能会发现在您编写的Complex()默认构造函数中添加一个额外的输出行很有趣,并查看它被调用了多少次。您将看到,虽然有4个复杂对象,但构造函数只被调用了3次。operator()函数的返回值使用不同的构造函数(复制或移动),您尚未定义该构造函数,但已为您实现。如果您定义复制构造函数复合体(constcomplex&c){},您将看到它被调用作为返回值。这些其他构造函数是如何创建的以及何时创建的,这稍微涉及到一些问题……谢谢@David Schwartz!根据您的反馈,我更新了问题,以显示对代码
Complex nwobj=cmpx1+cmplx2的修改//用于将返回对象分配给左值的复制构造函数
这不一定是真的。在完全信任的情况下,我做了一个相反的解释。请注意,总共有三个构造函数调用,它们都不是复制构造函数。@Scheff如果我在OP的代码中定义了
Complex(const Complex&){}
,那么它确实会在Complex c3=c1+c2行中被调用。如果我还定义了被调用的
Complex(Complex&)
。如果我将
操作符+
定义修改为
返回复数(real+obj.real,imag+obj.imag)则两者都不会被调用(我假设是因为优化)。我确实定义了
Complex(const Complex&)
并且没有忘记使用
std::cout
的“诊断”输出。(Btw.也有3个析构函数调用)问题是,你使用了什么编译器(用C++标准)?我使用了
g++-std=c++17
。(在C++17中,复制省略是必须的。)我忘了提到这个…;-)当然,我添加了move构造函数和move赋值,尽管我已经知道这不会改变任何事情:如果你还不确信,我也会在
Complex::operator+()
中打印本地
res
的地址,它与
c3
中的地址一样:
Address inside the function 0x7fffbc955610
Address outside the function 0x7fffbc955650
int foo()
{
    int i = 2;
    return i;
}
Complex  nwobj=cmpx1 + cmplx2; //copy constructor used to assign return object to lvalue

cmplx3=cmplx1+xmplx2;//operator= used to make a right assignment.