在初始化具有函数的返回值的对象时,不会调用复制构造函数 [英] Copy constructor not called when initializing an object with return value of a function

查看:175
本文介绍了在初始化具有函数的返回值的对象时,不会调用复制构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

#include <iostream>

using namespace std;

class A
{
    public:
        int a;
        A(): a(5)
        {
           cout << "Constructor\n";
        }
        A(const A &b)
        {
            a = b.a;
            cout << "Copy Constructor\n";
        }
        A fun(A a)
        {
            return a;
        }
};

int main()
{
    A a, c;
    A b = a.fun(c);
    return 0;
}

上述代码与 g ++文件的输出。 cpp 是:

Constructor
Constructor
Copy Constructor
Copy Constructor

上述代码的输出为 g ++ -fno-elide-构造函数file.cpp 是:

Constructor
Constructor
Copy Constructor
Copy Constructor
Copy Constructor

我知道返回值优化。我的问题是调用拷贝构造函数(返回过程中的临时对象或返回的对象被复制到B)被省略?

I know Return Value Optimization. My question is which call to copy constructor is elided(temporary object during returning or returned object being copied to b)?

如果消隐拷贝构造函数用于创建一个b,则是如何b。在所有已创建的(因为在这种情况下,也没有构造函数调用)?

If the elided copy constructor is the one used for creating b, then how is b created at all (because there is no constructor call in this case also)?

如果我更换行 A b = a.fun(C); a.fun(C)和编译使用第一种方法,甚至第二种方法,那么也拷贝构造函数被调用了2次。所以,如果在案件上段所述,临时对象的拷贝构造函数会被省略,那么为什么是不是在这种情况下省略?

If I replace the line A b = a.fun(c); with a.fun(c) and compile using the first method or even the second method, then also the copy constructor is being called 2 times . So, if in the case explained in the previous paragraph, the temporary object's copy constructor is elided, then why isn't it elided in this case?

推荐答案

#include <iostream>

using namespace std;

class A
{
public:
    int a;
    A(): a(5)
    {
        cout << "Constructing: " << (void *)this << std::endl;
    }
    A(const A &b)
    {
        a = b.a;
        cout << "Copy Constructor: " << (void *)this << " from " << (void *)&b << std::endl;
    }
    A fun(A a)
    {
        return a;
    }
};

int main()
{

    A a, c;
    A b = a.fun(c);

    std::cout << "a:" << (void *)&a << std::endl <<
              "b:" << (void *)&b << std::endl <<
              "c:" << (void *)&c << std::endl;
    return 0;
}

产量:

Constructing: 0x7fffbb377220
Constructing: 0x7fffbb377210
Copy Constructor: 0x7fffbb377230 from 0x7fffbb377210
Copy Constructor: 0x7fffbb377200 from 0x7fffbb377230
a:0x7fffbb377220
b:0x7fffbb377200
c:0x7fffbb377210

因此,它构造 a ,构造 c ,将 c 复制到中间(参数 code>的功能),然后直接复制中间插入 b ,跳过一个典型的复制到中间回报。如果你传递值(更改为 A fun(const A& a)

So it constructs a, constructs c, copies c to an intermediate (argument a of the function), and then copies the intermediate directly into b, skipping the typical copying of a to a return intermediate. This is even better demonstrated if you pass by value (change to A fun(const A& a):

Constructing: 0x7fff8e9642b0
Constructing: 0x7fff8e9642a0
Copy Constructor: 0x7fff8e964290 from 0x7fff8e9642a0
a:0x7fff8e9642b0
b:0x7fff8e964290
c:0x7fff8e9642a0

一个构造,C构造,C是直接复制到b,尽管b没有被传递到乐趣!

a is constructed, c is constructed, c is copied directly to b, despite b not being passed to fun!

这篇关于在初始化具有函数的返回值的对象时,不会调用复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆