有没有办法在类上禁用构造函数合成?

Joe*_*ner 12 c++ gcc

假设我有一个类,我想确保我的编译器(在这种情况下是GCC)不合成任何构造函数或赋值方法.我找到了一种方法来做这个,只是在类中包含一个const int成员,但这并没有让我感觉良好.是否有属性或某些东西表示这一点.

Naw*_*waz 31

如果您自己定义(或仅声明)它,那么编译器将不会为您定义它.

struct A
{
     A (); /*declaration is enough to prevent the compiler from 
             generating default constructor!*/
};
Run Code Online (Sandbox Code Playgroud)

虽然声明足以阻止编译器生成默认构造函数,但如果您的代码需要默认构造函数,则必须定义它,否则您将收到链接器错误.

在C++ 11(新的ISO标准)中,您可以禁用构造函数,复制构造函数和复制赋值,如下所示:

struct A
{
    A(const A&) = delete             //disable copy-constructor
    A& operator=(const A&) = delete; //disable copy-assignment
};
Run Code Online (Sandbox Code Playgroud)

现在有趣的部分

您还可以选择性地禁用所选类型的构造函数,这样会delete更有趣.想想这个,

struct A
{
       A (int) {}
};
Run Code Online (Sandbox Code Playgroud)

此类的对象不仅可以使用int参数创建,还可以使用隐式转换为的任何类型创建int.例如,

A a1(10);  //ok
A a2('x'); //ok - char can convert to int implicitly

B b; 
A a3(b); //ok - assume b provides user-defined conversion to int
Run Code Online (Sandbox Code Playgroud)

现在假设,无论出于何种原因,我不希望类的用户A使用char或创建对象class B,幸运或遗憾地可以隐式转换为int,然后您可以将它们禁用为:

struct A
{
     A(int) {}
     A(char) = delete;      //disable
     A(const B&) = delete;  //disable
};
Run Code Online (Sandbox Code Playgroud)

现在你走了:

A a1(10);  //ok
A a2('x'); //error

B b; 
A a3(b); //error - assume (even if) b provides user-defined conversion to int
Run Code Online (Sandbox Code Playgroud)

在线演示:http://ideone.com/ZVyK7

错误消息非常清楚:

prog.cpp:9:5:错误:删除函数'A :: A(char)'
prog.cpp:10:5:错误:删除函数'A :: A(const B&)'


Chr*_*zig 15

经典的方法是声明它们,但绝不实施.大多数人都希望声明是私密的或受到保护的.

在C++ 0x中,您可以显式删除它们.这几乎完全相同,但阅读方式更好.