首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11:未触发Move构造函数

C++11:未触发Move构造函数
EN

Stack Overflow用户
提问于 2014-01-30 13:04:36
回答 2查看 625关注 0票数 1

最近我一直在研究C++11中的移动语义,印象非常深刻,我迫不及待地想动手尝试一下。以下是我的代码:

代码语言:javascript
运行
复制
#include <iostream>
using namespace std;

class ArrayWrapper
{
public:
    // default constructor produces a moderately sized array
    ArrayWrapper ()
        : _p_vals( new int[ 64 ] )
        , _size( 64 )
    {
        cout << "Default constructor: " << this << endl;
    }

    explicit ArrayWrapper (int n)
        : _p_vals( new int[ n ] )
        , _size( n )
    {
        cout << "Constructor: " << this << endl;
    }


    // move constructor
    ArrayWrapper (ArrayWrapper&& other)
        : _p_vals( other._p_vals  )
        , _size( other._size )
    {
            cout << "Move constructor: " << this << endl;
            other._p_vals = NULL;
            other._size = 0;
    }


    // copy constructor
    ArrayWrapper (const ArrayWrapper& other)
        : _p_vals( new int[ other._size  ] )
        , _size( other._size )
    {
            cout << "Copy constructor: " << this << endl;
            for ( int i = 0; i < _size; ++i )
            {
                    _p_vals[ i ] = other._p_vals[ i ];
            }
    }
    ~ArrayWrapper ()
    {
            cout << "Destructor: " << this << endl;
            delete [] _p_vals;
    }

    void self () {
        cout << "This address: " << this << endl;
    }

public:
    int *_p_vals;
    int _size;
};

ArrayWrapper two() {
    ArrayWrapper a(7);
    cout << "Temp ArrayWrapper created!" << endl;
    return a;
}

int main() {
    ArrayWrapper b (two());
    b.self();
}

(我引用了1中的一些代码)

代码可能看起来很长,但实际上非常幼稚,只是一个转储数组。

在第67行,我特意创建了一个带有r值的b,并期望看到如何调用移动构造函数。但令人失望的是,这个程序的输出是:

代码语言:javascript
运行
复制
Constructor: 0x7fff51d60be0
Temp ArrayWrapper created!
This address: 0x7fff51d60be0
Destructor: 0x7fff51d60be0

打印的三个地址是相同的,而且根本不调用移动构造函数!实际上,我后来尝试删除了move构造函数,程序仍然编译并给出相同的输出!如果你仔细观察,你会发现在构造a时,构造函数只被调用一次,也就是说,当构造b时,根本不会调用任何构造函数,既不是move,也不是copy!

我真的很困惑。谁能告诉我为什么移动构造函数没有被触发,以及b到底是如何构造的?

EN

Stack Overflow用户

发布于 2014-01-30 13:30:27

您正在经历的情况称为复制省略--在某些上下文中可以跳过复制和移动构造函数,即使跳过它们会有明显的副作用。常见的情况包括RVO和NRVO (返回值优化和命名RVO)或来自匿名临时的复制初始化。

要阻止它,请在从函数返回的点显式调用std::move,并在main中构造值,因为std::move的右值强制转换使省略非法。std::move接受T&T&&并将其转换为T&&,以防止“左侧”执行省略,因为省略(至少在这一点上)被限制为某些狭义情况。

阻止省略通常是一个坏主意,但std::move可以做到这一点。

票数 5
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21448224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档