使用默认构造函数

时间:2016-08-10 05:33:29

标签: c++ c++11 constructor

查看this question它提到 C ++ 11及更高版本

  

如果没有用户声明的复制构造函数,复制赋值运算符或析构函数,并且生成的移动构造函数有效(例如,如果它不需要指定常量成员),则自动生成移动构造函数(§12.8) / 10)。

所以,如果我有以下代码:

class Y
{
public:
    Y(const Y&) {}
};

struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; 
};
hasY hy, hy2 = std::move(hy); //this line fails as expected as Y has a user-defined copy constructor.

现在,如果我将默认构造函数添加到Y:

Y() {}

错误消失。
在哪里说默认构造函数会导致创建移动构造函数?

(使用VS 2015更新2)

3 个答案:

答案 0 :(得分:3)

class Y
{
public:
    Y(const Y&) {}
};

这个类没有默认构造函数,所以

struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem;  // << requires default ctor
};

你得到的错误与移动构造函数无关:

prog.cpp: In function 'int main()':
prog.cpp:13:7: error: use of deleted function 'hasY::hasY()'
  hasY hy;
   ^
prog.cpp:8:5: note: 'hasY::hasY()' is implicitly deleted because the default definition would be ill-formed:
     hasY() = default;

http://ideone.com/u46GWS

答案 1 :(得分:0)

  

它在哪里说默认构造函数会导致创建移动构造函数?

移动构造函数的创建与默认构造函数的存在或缺乏之间没有关系。

来自C ++ 11标准:

  

12.8复制和移动类对象

     

...

     

9如果类X的定义没有显式声明一个移动构造函数,那么将隐式声明一个   当且仅当

时默认为      

- X没有用户声明的复制构造函数,

     

- X没有用户声明的复制赋值运算符

     

- X没有用户声明的移动赋值运算符

     

- X没有用户声明的析构函数,

     

- 移动构造函数不会被隐式定义为已删除。

答案 2 :(得分:0)

它与移动构造函数无关。它与默认构造函数有关。试试这个:

class Y
{
public:
    Y(const Y&) {}
};

struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; 
};
hasY hy; // This will cause an error because there is no default constructor

现在,如果你添加默认构造函数:Y(){},错误就会消失。

正如@ M.M评论的那样,复制构造函数将在这种情况下被调用。

您可以尝试以下代码:

class Y{
public:
    Y(){std::cout << "Default constructor\n";}
    Y(const Y&) {std::cout << "Copy constructor\n";}
};

struct hasY {
    hasY() = default;
    hasY(hasY&&) = default;
    Y mem; 
};

int main(){
    hasY hy;
    hasY h=std::move(hy);
}

它将打印:

  

默认构造函数

     

复制构造函数

如果您想让课程不可移动,您应该自己删除移动构造函数Y(Y&&)=delete;