默认的复制构造函数和赋值的类与移动构造函数和赋值 [英] Default copy constructor and assignment for class with move constructor and assignment

查看:436
本文介绍了默认的复制构造函数和赋值的类与移动构造函数和赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个类:

class Test
{
public:
    Test();
};



<实例。现在我添加move构造函数和赋值:

AFAIK, compiler provides default copy constructor and assignment operators, which assign every member of other instance to the current instance. Now I add move constructor and assignment:

class Test
{
public:
    Test();
    Test(Test&& other);
    Test& operator=(Test&& other);
};

这个类是否还包含编译器生成的拷贝构造函数和赋值运算符,

Does this class still contain compiler-generated copy constructor and assignment operators, or I need to implement them?

编辑。这是我的测试:

class Test
{
public:
    Test(){}

    Test(Test&& other){}
    Test& operator=(Test&& other)
    {
        return *this;
    }

    int n;
    char str[STR_SIZE];
};

int main()
{
    Test t1;
    t1.n = 2;
    strcpy(t1.str, "12345");

    Test t2(t1);

    Test t3;
    t3 = t1;

    cout << t2.n << " " << t2.str << " " << t3.n << " " << t3.str << endl;

    return 0;
}

列印 2 12345 2 12345 。编译器:VC ++ 2010.根据这个测试,拷贝构造函数和赋值仍然在这里。

Prints 2 12345 2 12345. Compiler: VC++ 2010. According to this test, copy constructor and assignment are still here. Is this standard behavior, can I be sure that this will work on every C++ compiler?

推荐答案

12.8-7这是标准的行为,我可以确定这将在每个C ++编译器上工作吗?复制和移动类对象[class.copy]


如果类定义没有显式声明一个复制构造函数,声明为隐式。如果类定义声明了move构造函数或move赋值运算符,则隐式声明的拷贝构造函数定义为deleted;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,后一种情况将被弃用...

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor...

strong> 12.8-18

From 12.8-18


如果类定义没有显式声明一个复制赋值运算符,如果类定义声明了一个移动构造函数或移动赋值操作符,则隐式声明的复制赋值操作符被定义为删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则后一种情况不推荐使用...

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor...

,因为您已声明了移动构造函数移动赋值运算符,但没有复制赋值运算符,复制构造函数或析构函数,因此您获取隐式生成的复制构造函数或赋值运算符。编译器给你他们的声明,但它们被声明为 deleted

According to this, since you have declared a move constructor and a move assignment operator, but no copy assignment operator, copy constructor or destructor, you do not get the implicitly generated copy constructor or assignment operator. The compiler gives you their declarations, but they are declared as deleted.

是您的示例的简化版本:

Here is a simplified version of your example:

struct Test
{
public:
    Test(){}
    Test(Test&& other){}
    Test& operator=(Test&& other) { return *this;}
};

int main()
{
  Test t1;
  Test t2(t1);
}

由g ++ 4.8.1产生的错误

And the error produced by g++ 4.8.1


ctors.cpp:13:13:错误:使用已删除的函数'constexpr Test :: Test(const Test&)'

ctors.cpp:13:13: error: use of deleted function 'constexpr Test::Test(const Test&)'

测试t2(t1);

ctors.cpp:1:8:注意:'constexpr Test :: Test(const Test&)'隐含声明为已删除,因为Test声明了一个移动构造函数或移动赋值运算符

ctors.cpp:1:8: note: 'constexpr Test::Test(const Test&)' is implicitly declared as deleted because 'Test' declares a move constructor or move assignment operator

struct Test

struct Test

(强调我)

这篇关于默认的复制构造函数和赋值的类与移动构造函数和赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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