2013-09-17 3 views
12

Ранее сегодня я спросил a question, что привело к другому: когда следует использовать =delete? Я не думаю, что есть статья, посвященная исключительно =delete на SO, поэтому я просмотрел ее в книге под названием «Язык программирования C++». Я приведу свои выводы в свой ответ ниже.Что такое использование для = delete?

Просьба прокомментировать или ответить, если есть что сказать или если я ошибаюсь.

+0

@Rapptz Я видел этот пост, но я думал, что это о том, что '= default' и' = delete' ** do **. Это касается реального использования '= delete'. Легко понять, что '= delete' запрещает использование функции, но почему на Земле вы хотели бы это сделать? Это сообщение отвечает, почему. – Oleksiy

+0

это запах рыбный ... –

+0

«У этого вопроса уже есть ответ здесь ...» - гм, нет, нет. Несмотря на то, что эти вопросы связаны, они не дублируются. – Oleksiy

ответ

29

Оказалось, что =delete чрезвычайно полезна! Вот несколько примеров:


В основном мы можем предотвратить копирование базовых классов, поскольку это может часто приводить к нарезке:

struct Base { 

    Base(){} 

    Base& operator=(const Base&) = delete; // disallow copying 
    Base(const Base&) = delete; 

    Base& operator=(Base &&) = delete;  // disallow moving 
    Base(Base &&) = delete; 

}; 

struct Der : public Base {}; 

void func() { 

    Der d; 
    Base base = d; // this won't work because the copy constructor is deleted! 
        // this behavior is desired - otherwise slicing would occur 

} 

Это также полезно, когда шаблон функция не может работать с определенным Тип:

template<class T> 
void fn(T p) { /* ... */ }; // do something with T 

void fn(int) = delete; // disallow use with int 

void fun() { 

    fn(4);  // aha! cannot use fn() with int! 
    fn(-4.5); // fine 
    fn("hello");// fine 
} 

=delete также может запретить нежелательные преобразования:

struct Z { 

    Z(double); // can initialize with a double 
    Z(int) = delete; // but not with an integer 

}; 

void f() { 

    Z z1 { 1 }; // error! can't use int 
    Z z2 { 1.0 }; // double is ok 

} 

Некоторые более продвинутые применения =delete включают запрещающее стек или свободное распределение магазина:

class FS_Only { 
    ~FS_Only() = delete; // disallow stack allocation 
}; 

class Stack_Only { 
    void* operator new(size_t) = delete; // disallow heap allocation 
}; 

... Вы получаете идею. Надеюсь, это поможет кому-то! =delete может помочь написать читаемый, неточный и элегантный код.


Edit:

Как правильно отмечено в комментариях, теперь невозможно удалить FS_Only объекты, так что это один не такой хороший использование =delete после всех.

+1

Ничего себе, единственное, что я знал, - это запретить копирование. Я не ожидаю так много других применений. –

+4

Деструктор вызывается также, когда вы «удаляете» объект, выделенный в куче, поэтому, помечая деструктор как удаленный, вы создаете класс, который вы можете использовать для выделения в куче, но * никогда * не удаляете. –

+1

Ничего себе, с каждой новой версией спецификации C++. он становится все менее узнаваемым как язык. Это звучит полезно, но мальчик, этот синтаксис - это полное бельмо на глазах у такого динозавра, как я. –

Смежные вопросы