30

下面的snipplet是否适用于为类定义所有其他方法生成的方法和构造函数?在类中正确使用`= delete`方法

struct Picture { 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no accidental construction, i.e. temporaries and the like 
    Picture() = delete; 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 

    // no move 
    Picture(Picture&&) = delete; 

    // no move-assign 
    Picture& operator=(Picture&&) = delete; // return type correct? 
}; 

这将删除每个默认的编译器实现,只留下析构函数,对不对?如果没有它,我猜可能会(几乎)不可用,但我可以删除它,对吗?

返回类型Picture&的移动分配operator=(Picture&&)是否正确?如果我为返回类型写了Picture&&,它会有所作为吗?

+3

看起来好像C++在C++ 0x!中真的改变了很多,有趣的东西。 – briantyler 2011-04-16 14:19:55

+1

这是一个更清晰的语法,然后将这些方法隐藏在“private”部分中,并且只声明*但不定义*它们。 – towi 2011-05-27 08:03:39

回答

26

除了Xeo的回答:

是的,一切都是正确的。如果你想,你可以消除所有被删除的成员,但被删除的拷贝构造函数和删除拷贝赋值,并有同样的效果:

struct Picture { // Also ok 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 
}; 

拷贝构造函数的显式声明禁止默认构造函数的隐代,移动构造函数和移动赋值成员。明确删除这些成员是一个有趣的问题。有些人可能认为它是很好的文档。其他人可能认为它过于冗长。

+1

谢谢,我在草稿中忽略了这一点。这节省了打字时间。如果我想要他们,我认为我可以'他们=默认'? – towi 2011-04-16 17:02:59

+1

是的。你可以明确地默认它们或明确地删除它们。 – 2011-04-17 03:44:35

3

对我来说似乎很好。 operator=的返回值必须是是一个正常参考,即使该对象是由右值引用构造的。这是因为你不能只将左值(*this)编译为右值。
而且它应该采用每个非常数的右值参考Picture& operator=(Picture&&)。你将如何从一个不变的物体移动? ;)

+0

当然,我多么愚蠢。你在两个账户上都是对的。让我在问题中纠正它,所以读者不从我错误的例子中学习。 – towi 2011-04-16 15:27:41