2011-08-29 114 views
8

我在看C++ 11的新功能,其中一个令我困惑,因为我找不到在真实世界中使用它的方法。删除和默认功能实际世界范例

它的删除和默认功能,有没有人有它的使用的真实世界的例子,或者它只是其中一个功能,只是增加了一些糖?

回答

8
struct A 
{ 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    // by writing copy constructor, we suppress the generation of 
    // implicit default constructor A::A() 

    int data; 
}; 

void foo1() 
{ 
    A a; // does not work, since there's no default constructor 
} 

比方说,我们的默认构造函数没有做什么特别的事情,是(或多或少)等于给编译器生成一个。我们可以通过编写我们自己的默认构造函数(这可能会很麻烦,如果我们班有很多非静态成员)修理,或使用= default语法:

struct A 
{ 
    A() = default; 
    A(const A& arg) : data(arg.data) 
    { 
    do_something_special(); 
    } 

    int data; 
}; 

删除功能是非常有用的,当我们希望禁止使用特定的重载或模板特化,或者仅限于禁止复制(或移动)对象。

void foo(char c) {} 
void foo(int i) = delete; // do not allow implicit int -> char conversion 

当你想禁止复制(即线程对象),通常惯用的方法是申报私人拷贝构造函数没有实现(是的,或者使用boost ::不可复制)。虽然这适用于大多数情况,但有时您可能会遇到一些模糊的链接器错误。试想一下:

struct A 
{ 
    A() = default; 

    friend void foo(); 

private: 
    A(const A&); 
}; 

void foo() 
{ 
    A a; 
    A b(a); // results in linker error in gcc 
} 

制作A(const A&)删除,我们避免潜在的连接错误,使我们的意图(禁止复制)很清楚。

9

用户声明的特殊成员函数不是微不足道的。如果一个类有任何不平凡的特殊成员函数,那么这个类不是POD。因此,这种类型的POD:

struct S { 
    S() = default; 
    S(int) { } 
}; 

但这种类型不是POD:

struct S { 
    S() { } 
    S(int) { } 
}; 
+0

@Christian的例子:如果我们只是有'的struct {S(INT){}};','的S(INT)的存在下将'禁止隐式声明的默认构造函数。 –

+0

POD的规则已经在C++ 0x/11中放宽了,所以你的第二个例子也是C++ 0x/11中的POD。例如,您还可以使用新特征 :: is_pod来检查自己是否具有静态断言。 – David

+0

@大卫:POD的规则确实放宽了,但第二个'S'仍然不是POD。 POD结构必须是一个平凡的类。一个普通的类必须有一个简单的默认构造函数。用户提供的默认构造函数不是微不足道的。第二个'S'有一个用户提供的默认构造函数,因此不是POD。 –

1

对于您想要防止复制或直接实例化的类(例如,您想要执行get_instance()函数的单例),您可以使用已删除的函数。你冷漠也使用删除来防止你的构造函数的某些变化。

如果您希望编译器生成的任何隐式生成的构造函数,默认情况下很有用。例如,如果您创建自定义参数构造函数,编译器将不会生成默认的无参数,因此您可以要求使用default关键字为其生成。

在这里看到上述

http://www2.research.att.com/~bs/C++0xFAQ.html#default