2017-04-15 39 views
1

项目17:了解特殊的成员函数生成。“有效的现代C++”中的C++默认移动操作

  1. 移动的操作仅支持入级缺乏
    明确宣布移动操作产生,复制操作, 或析构函数。

  2. 现在,当我指的是移动操作布展施工
    或移动,分配数据成员或基类,有
    不能保证此举将实际发生。
    “成员移动”实际上更像是成员移动
    移动请求,因为未启用移动的类型(...)
    将通过其复制操作“移动”。

但是,我无法在我的环境中验证它们。

// compiled 
#include <iostream> 
using namespace std; 
class Base { 
public: 
    ~Base() {} 
}; 
int main() { 
    Base a, c; 
    Base b(move(a)); 
    c = move(b); 
    // explicitly destructor does not disable 
    // default move constuctor and move assignment operator 
    return 0; 
} 

class Base { 
public: 
    Base() {} 
    Base(Base& b) {} 
    ~Base() {} 
}; 
class Num { 
private: 
    Base b; 
}; 
int main() { 
    Num a, c; 
    c = move(a); // passed 
    Num b(move(c)); // error 
    // explicitly Base::Base(Base& b) disable default move 
    // move conctructor. 
    // Num's default move constructor can not find any move 
    // constructor for member object Base b, which lead to an 
    // error. Num's default move constructor does not "moved" 
    // Base b via their copy operations which is declared. 
    return 0; 
} 

的第一个断言可能从环境会有所不同,但第二个几乎是错的。
我对此很困惑。 请帮我一把。

回答

0
class Base { 
public: 
    ~Base() {} 
}; 

因为Base有一个用户声明析构函数,它不具有移动构造函数或在所有移动赋值运算符。行

Base b(move(a)); 
c = move(b); 

分别实际调用复制构造函数和复制赋值运算符。

class Base { 
public: 
    Base() {} 
    Base(Base& b) {} 
    ~Base() {} 
}; 
class Num { 
private: 
    Base b; 
}; 

此外,Base根本没有移动构造函数。但是,Num确实有一个隐式声明的移动构造函数,因为Num本身没有声明任何特殊的成员函数。但是,隐式定义为删除,因为默认情况下的定义是非法的构造:

Num::Num(Num&& n) : b(std::move(n.b)) {} 
// Cannot convert rvalue of type `Base` to `Base&` 
// for the copy constructor to be called. 

。注意的b“移动”确实尝试使用拷贝构造函数,但它不能。

+0

感谢您的解释!我现在很清楚! – gfxcc