Есть ли способ отключить синтез конструктора в классе?

Предположим, у меня есть класс, который я хочу, чтобы мой компилятор (GCC в этом случае) не синтезировал никаких конструкторов или методов назначения для. Я нашел один способ сделать это, который должен включать только член const int в классе, но это не раздражает меня. Есть ли атрибут или что-то, что означает это.

Ответ 1

Если вы определяете (или только объявляете) его самостоятельно, то компилятор не будет определять его для вас.

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

Пока объявления достаточно, чтобы компилятор не создавал конструктор по умолчанию, необходимо определить его , если для вашего кода требуется конструктор по умолчанию, иначе вы получите ошибку компоновщика.

В С++ 11 (новый стандарт ISO) вы можете отключить конструкторы, copy-constructor и copy-assign как:

struct A
{
    A(const A&) = delete             //disable copy-constructor
    A& operator=(const A&) = delete; //disable copy-assignment
};

Теперь интересная часть

Вы также можете выборочно отключить конструктор для выбранных типов, что делает delete более интересным. Рассмотрим это,

struct A
{
       A (int) {}
};

Объект этого класса может быть создан не только с аргументом 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

Теперь предположим, что по какой-то причине я не хочу, чтобы пользователи класса A создавали объекты с char или class B, которые, к счастью или к сожалению, могут неявно конвертировать в int, тогда вы можете отключить их как:

struct A
{
     A(int) {}
     A(char) = delete;      //disable
     A(const B&) = delete;  //disable
};

Теперь вы идете:

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

B b; 
A a3(b); //error - assume (even if) b provides user-defined conversion to int

Онлайн-демонстрация: http://ideone.com/ZVyK7

Сообщения об ошибках очень понятны:

prog.cpp: 9: 5: ошибка: удаленная функция "A:: A (char)"
prog.cpp: 10: 5: ошибка: удаленная функция 'A:: A (const B &)'

Ответ 2

Классический способ - объявить их, но никогда не применять. Большинство людей ожидали бы, что декларация будет частной или защищенной.

В С++ 0x вы можете явно удалить их. Что делает почти то же самое, но лучше читать.