10

Это просто быстрый вопрос правильно понять, что происходит, когда вы создаете класс с конструктором, как это:компилятором Конструкторы

class A 
{ 
    public: 
    A() {} 
}; 

Я знаю, что конструктор по умолчанию не создается, поскольку она уже определена, но являются копировать и присваивать конструкторы, сгенерированные компилятором, или, другими словами, мне нужно, чтобы объявить частный конструктор копирования и частный оператор назначения, чтобы предотвратить это?

class A 
{ 
    private: 
    // needed to prevent automatic generation? 
    A(const A&); 
    A& operator=(const A&); 
    public: 
    A() {} 
}; 

ответ

10

Да. Конструктор копирования, оператор присваивания и деструктор всегда создаются независимо от других конструкторов и операторов.

Если вы хотите отключить его, то, что у вас там, идеально. Это тоже довольно распространено.

+0

Действительно, хотя, если вы используете это, чтобы предотвратить копирование/назначение, проверить [повышение :: noncopyable] (HTTP: // WWW .boost.org/DOC/LIBS/1_55_0/LIBS/утилиты/utility.htm # Class_noncopyable). (Вы можете вырвать этот простой класс или написать свое собственное и использовать его везде, где хотите.) – TypeIA

13

Да, создатели копий и операторы присваивания копий все еще созданы, даже если вы объявляете свой собственный конструктор по умолчанию.

Создание этих объектов подавляется только в том случае, если вы объявляете свой собственный конструктор копирования или оператор присваивания копии в определении класса соответственно.

Обратите внимание, что можно иметь и свой собственный конструктор копирования, и компилятор при условии одно:

struct A { 
    A() { } 
    A(A const&, int foo); 
}; // compiler declares a copy constructor now 

// make the second parameter have a default argument 
// now this constructor is a copy constructor too. 
inline A::A(A const&, int foo = 0) { 

} 

int main() { 
    A a; 
    A b = a; // ambiguity between compiler's one and our custom one! 
} 

Стандарт однако позволяет составителям принять этот код - но эффект аналогичен имеющий неопределенное поведение: Программа плохо сформирована, но для этой программы не требуется никаких предупреждений/ошибок. (ранние версии GCC не отклоняют этот код, последние отвергают его).

+1

Ваши сообщения «как обычно» очень информативны :) –

2

Если вы хотите отключить копирование и назначение, то лучше наследовать от класса, который имеет частный конструктор копирования и оператор присваивания (boost::noncopyable - готовый).

1) Меньше повторения ввода.

2) Самодокументируемое (надеюсь).

3) Более сильная проверка того, что эти операции не могут быть вызваны (сам класс и друзья могут делать копии), что приведет к компилятору, а не к ошибке компоновщика).

4) не скроет конструктор по умолчанию :)

#include <boost/noncopyable.hpp> 

class X : boost::noncopyable 
{ 
}; 

int main() 
{ 
    X a, b;  //has default constructor 
    //X c(a); //but can't be copied 
    //a = b; //or assigned 
} 
Смежные вопросы