按值调用函数时缺少复制构造函数调用

时间:2019-05-01 14:03:26

标签: c++11

首先,如果有不清楚的地方,我表示歉意,这是我在这里的第一篇文章。

所以我遇到了C ++ 11问题...我经常使用这种语言,最近我接触了移动语义。因此,我开始玩一个玩具示例,以清楚地了解发生了什么以及何时发生。但是我遇到了一些我不了解的东西,甚至没有涉及移动语义(我认为)...

在进一步的细节中,我编写了一个非常简单的类X-一个围绕int数组的包装器-在其中我明确定义了默认构造函数以及复制构造函数,复制构造函数,复制分配运算符,move构造函数,move分配运算符和析构函数(出于完整性考虑)。他们都打印一条消息。

由此,我添加了两个其他函数:一个函数创建一个X实例,另一个函数按值获取一个X实例并显示它。

代码是:

#include <iostream>

class X
{   public :
    int size ;
    int* arr ;

    // default constructor
    X()
    {   std::cout << "default constructor" << std::endl ;
        size = 0 ;
        arr = nullptr ;
    }

    // copy constructor
    X(const X& rhs)
    {   std::cout << "copy constructor" << std::endl ;
        size = rhs.size ;
        arr  = new int[size] ;
        for(int i=0; i<size; i++)
        {   arr[i] = rhs.arr[i] ; }
    }

    // copy assignment operator
    X& operator=(const X& rhs)
    {   std::cout << "copy assignment" << std::endl ;
        size = rhs.size ;
        arr  = new int[size] ;
        for(int i=0; i<size; i++)
        {   arr[i] = rhs.arr[i] ; }
        return *this ;
    }

    // move constructor
    X(X&& rhs)
    {   std::cout << "move constructor" << std::endl ;
        size = rhs.size ;
        // transfer ownership
        arr  = rhs.arr ;
        rhs.arr = nullptr ;
    }

    // move assignment operator
    X& operator=(X&& rhs)
    {   std::cout << "move assignment" << std::endl ;
        size = rhs.size  ;
        arr  = rhs.arr ;
        rhs.arr = nullptr ;
        return *this ;
    }

    // destructor
    ~X()
    {   std::cout << "destructor" << std::endl ;
        if(arr != nullptr)
        {   delete arr ;
            arr = nullptr ;
        }
    }

} ;

// simply receives an X object by value and displays it.
void foo(X x)
{
    std::cout << "----- foo(X) -----" << std::endl ;
    for(int i=0; i<x.size; i++)
    {   std::cout << x.arr[i] << " " ; }
    std::cout << std::endl ;
}

// creates an X object and returns it.
X createX()
{   std::cout << "----- createX() -----" << std::endl ;
    X x ;
    x.size=4 ;
    x.arr = new int[x.size] ;
    for(int i=0; i<x.size; i++)
    {   x.arr[i] = i ; }
    return x ;
}

int main()
{
    X x = createX() ;
    foo(x) ;
    foo(createX()) ;

    return 0 ;
}

我期望得到以下结果:

----- createX() -----
default constructor    // inside createX()
copy constructor       // in the main(), 1st foo() call
----- foo(X) -----
0 1 2 3
destructor             // upon return from foo()
----- createX() -----
default constructor    // inside createX()
copy constructor       // in the main(), 2nd foo() call
----- foo(X) -----
0 1 2 3 
destructor             // upon return from foo()
destructor             // upon return from main()

但是我得到了这个:

----- createX() -----
default constructor
copy constructor
----- foo(X) -----
0 1 2 3 
destructor
----- createX() -----
default constructor
----- foo(X) -----     // missing the expected copy constructor call
0 1 2 3
destructor
destructor

缺少我期望的第二条“复制构造函数”消息。那么...第二次调用foo()会发生什么?如果不使用复制构造函数或移动构造函数复制匿名实例,如何将其赋予foo()?

0 个答案:

没有答案