Почему я должен удалить конструктор перемещения и перемещения оператора присваивания в синглтон?

у меня есть следующая реализация Одноэлементного класса политики:

template <typename T>
class Singleton
{
    Singleton(){}; // so we cannot accidentally delete it via pointers
    Singleton(const Singleton&) = delete; // no copies
    Singleton& operator=(const Singleton&) = delete; // no self-assignments
    Singleton(Singleton&&) = delete; // WHY?
    Singleton& operator=(Singleton&&) = delete; // WHY?
public:
    static T& getInstance() // singleton
    {
        static T instance; // Guaranteed to be destroyed.
                       // Instantiated on first use.
                       // Thread safe in C++11
        return instance;
    }
};

который я затем использую через любопытно повторяющийся шаблон шаблона (CRTP)

class Foo: public Singleton<Foo> // now Foo is a Singleton
{
    friend class Singleton<Foo>;
    ~Foo(){}
    Foo(){};
public:
// rest of the code
};

Я не могу понять, почему я должен удалить конструктор перемещения и оператор присваивания. Можете ли вы дать мне один пример, где я в конечном итоге нарушаю синглтон, если я не удаляю (не определяю вообще) оператор move ctor и assignment?

1 ответов


Если объявить конструктор копирования (даже если вы определяете его как deleted в объявлении), ни один конструктор перемещения не будет объявлен неявно. Ср. C++11 12.8 / 9:

Если определение класса X явно не объявляет конструктор перемещения, он будет неявно объявлен как defaulted тогда и только тогда, когда

- X не имеет объявленного пользователем конструктора копирования,

- ...

Так как у вас есть объявленный пользователем конструктор копирования, не будет конструктора перемещения вообще, если вы его не объявите. Таким образом, вы можете просто полностью избавиться от объявления-определения конструктора перемещения. То же самое для оператора Move-assignment.