C ++将分配移动到未初始化的对象? [英] C++ move assignment to uninitialized object?
问题描述
后续操作:
使用副本构造函数后,子对象的双重释放
我遵循建议的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屋!