C ++将分配移动到未初始化的对象? [英] C++ move assignment to uninitialized object?

查看:76
本文介绍了C ++将分配移动到未初始化的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

后续操作:
使用副本构造函数后,子对象的双重释放

我遵循建议的5规则。
但是现在似乎在未初始化的对象(对象ID为0)上发生了移动分配?我希望它从对象3移到对象2。

I followed the rule of 5 as suggested. But now it seems like the move assignment is happening on an uninitialized object (to object id 0)? I expected it to move from object 3 to object 2.

我创建了以下(最低要求)示例,似乎触发了我的问题:

I have created the following (minimum?) example which seems to trigger my issue:

#include <stdio.h>
#include <stdint.h>

class A
{
public:
    A()
    {
        myCtr = ++ctr;
        printf("class A default Constructor - object id: %u\n", myCtr);
    }

    A(const A &a2) {
        myCtr = ++ctr;
        printf("class A copy constructor - object id: %u\n", myCtr);

    }

    A(A &&a2) {
        myCtr = a2.myCtr;
        a2.myCtr = 0;

        printf("class A move constructor - object id: %u\n", myCtr);

    }

    A & operator=(const A &a2) {
        myCtr = ++ctr;

        printf("class A copy assignment - from object id: %u - to object id: %u\n", a2.myCtr, myCtr);

        return *this;
    }

    A & operator=(A &&a2) {
        printf("class A move assignment - from object id: %u - to object id: %u\n", a2.myCtr, myCtr);

        if (this != &a2) {
            //myCtr = a2.myCtr;
            //a2.myCtr = 0;
        }

        return *this;
    }

    ~A()
    {
        printf("class A destructor - object id: %u\n", myCtr);
    }

private:
    uint64_t myCtr;
    static uint64_t ctr;
};

class B
{
public:
    B() {

    }

    B(char * input, uint32_t len) {
        for (uint32_t i = 0; i < len; i++)
        {
            /* do something */
        }
    }

    B(const B &b2) {
        characters = A(b2.characters);
    }

    B(B &&b2) {
        characters = A(b2.characters);
    }

    B & operator=(const B &b2) {
        characters = A(b2.characters);
    }

    B & operator=(B &&b2) {
        characters = A(b2.characters);
    }

    ~B() {

    }


private:
    A characters;
};

uint64_t A::ctr = 0;

int main(int argc, char *argv[]) {
    B b1 = B((char *)"b1", 2);
    B b2 = b1;

    return 0;
}

这将产生以下输出:

class A default Constructor - object id: 1
class A default Constructor - object id: 2
class A copy constructor - object id: 3
class A move assignment - from object id: 3 - to object id: 0
class A destructor - object id: 3
class A destructor - object id: 2
class A destructor - object id: 1

这是我没想到的行:

类A移动分配-从对象ID:3-到对象ID:0

期望:

class一个移动分配-从对象ID:3-到对象ID:2

我正在使用以下编译器:Microsoft(R)C / C ++优化编译器版本19.14.26429.4

I am using the following compiler: Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26429.4

在万一你投反对票。请说明原因。我会很乐意尝试改善我的问题。

In case you down vote. Please specify why. I will gladly try to improve my question.

编辑:

似乎只有Visual C ++针对x86平台的编译器使此问题发生。它可以在g ++(x86和x64),clang(x86和x64)和msvc(x64)上正常工作。

推荐答案

在构造函数中

B(const B &b2) {
    characters = A(b2.characters);
}

首先创建类型A的临时对象,然后将其移动到 characters 变量。这就是为什么发生移动分配的原因。

You firstly create temporary object of type A and then move it to the characters variable. This is why move assignment happens.

尝试用以下方式替换此构造函数:

Try to replace this constructor by:

B(const B &b2) : characters(b2.characters)
{   
}

,您将获得预期的结果( https://ideone.com/yqvINu,以VS为例: http://rextester.com/PTPZKR93068 )。

and you will get the result which you predict (https://ideone.com/yqvINu, VS example: http://rextester.com/PTPZKR93068).

这篇关于C ++将分配移动到未初始化的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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