Ответ 1
Да. Конструктор копирования, оператор присваивания и деструктор всегда создаются независимо от других конструкторов и операторов.
Если вы хотите отключить его, то, что у вас там, идеально. Это тоже довольно распространено.
Это просто быстрый вопрос, чтобы правильно понять, что происходит, когда вы создаете класс с таким конструктором:
class A
{
public:
A() {}
};
Я знаю, что конструктор по умолчанию не создается, поскольку он уже определен, но являются конструкторами копирования и присваивания, сгенерированными компилятором, или, другими словами, мне нужно объявить частный конструктор копирования и частный оператор присваивания, чтобы предотвратить это?
class A
{
private:
// needed to prevent automatic generation?
A( const A& );
A& operator=( const A& );
public:
A() {}
};
Да. Конструктор копирования, оператор присваивания и деструктор всегда создаются независимо от других конструкторов и операторов.
Если вы хотите отключить его, то, что у вас там, идеально. Это тоже довольно распространено.
Да, операторы копирования и назначения копирования все еще созданы, даже если вы объявляете свой собственный конструктор по умолчанию.
Создание этих объектов подавляется только в том случае, если вы объявляете свой собственный конструктор копирования или оператор присваивания копии в определении класса соответственно.
Обратите внимание, что возможно иметь как собственный конструктор копирования, так и один компилятор:
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 one and our custom one!
}
Однако стандарт позволяет компиляторам принимать этот код, но эффект похож на поведение undefined: программа плохо сформирована, но для этой программы не требуется никаких предупреждений/ошибок. (ранние версии GCC не отклоняют этот код, последние отвергают его).
Если вы хотите отключить копирование и назначение, тогда лучше унаследовать класс, который имеет частный конструктор копирования и оператор присваивания (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
}