Есть ли способ отключить синтезатор конструктора в классе? - PullRequest
12 голосов
/ 22 августа 2011

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

Ответы [ 2 ]

30 голосов
/ 22 августа 2011

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

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

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

В C ++ 11 (новый стандарт ISO) вы можете отключить конструкторы, конструктор копирования и назначение копирования как:

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 (символ)'
prog.cpp: 10: 5: ошибка: удалена функция 'A :: A (const B &)'

15 голосов
/ 22 августа 2011

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

В C ++ 0x вы можете явно удалить их. Который делает почти то же самое, но читать намного приятнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...