2013-09-17 4 views
13

Я прочел this вопрос, но это все еще не имеет для меня большого смысла. Он по-прежнему звучит скорее как функция покрытия сахаром.delete modifier vs declaring function as private

Какая разница между:

class A 
{ 
// public/private ? 
    A (const A&) = delete; 
}; 

и

class A 
{ 
private: 
    A (const A&); // MISSING implementation 
}; 

То же самое для operator= или других функций.

+2

Выполнение их 'private' не останавливает вас (разработчик класса), называя их случайно. – Simple

+1

@ Простой - исполняемый файл не будет создан, если вы попробуете его называть. –

+0

Я считаю, что это технически некорректная программа без необходимости диагностики. Вы также получите ошибку компоновщика, а не ошибку компилятора. – Simple

ответ

17

Отличие заключается в том, что =delete позволяет время компиляции ошибки, а в некоторых случаях декларация без определения только пойманных на время компоновки (при которой сообщение об ошибке, как правило, не указывая вас к источнику проблема). Одним из таких случаев является добавление функции-члена, которая пытается скопировать экземпляр A. Даже если это не функция-член от A, сообщение об ошибке с копией-ctor составляет private не так ясно, как с использованием =delete.

Чтобы избежать путаницы, я рекомендую вам удалить удаленную функцию public, так как в противном случае вы получите дополнительные и вводящие в заблуждение сообщения об ошибках.

+0

Я согласен с этим ответом, так как он четко выделяет время компиляции/ссылки **, но ** Я хотел бы добавить здесь, что без модификатора 'delete' ошибка может быть обнаружена событием ** AT RUNTIME ** - см. комментарий ниже вопроса by @MatthieuM. –

+0

@KirilKirov Тогда вы можете рассмотреть возможность различения времени загрузки и времени выполнения. Большинство проблем при использовании библиотек DLL/разделяемых библиотек возникают во время загрузки, только если вы вручную и динамически загружаете библиотеки DLL/разделяемые библиотеки в свой код, у вас будет реальная ошибка во время выполнения. Правило при разработке кода: Предпочитайте время компиляции по времени привязки к времени загрузки по ошибкам во время выполнения. '= Delete' позволяет повысить класс проблем от младших классов до« лучшего »класса (ошибка компилятора) с улучшенной диагностикой. –

+0

Да, я знаю об этом. Я имел в виду именно ручную загрузку разделяемых библиотек, например, с помощью 'dlopen'. –

11

Разница в том, что цель кода =delete является явной в своей цели. Объявлять функции как private/недоступным было трюком. Хотя большинство людей это понимало, возникшая ошибка была неясной (ошибка уровня соединения/уровня доступа вместо семантической проблемы в коде - т. Е. «Вы используете удаленную функцию»).

+0

Другими словами - сахарное покрытие? :) –

+3

:) Другими словами, они превратили неловкое обходное решение в функцию. Я бы не назвал это сахарным покрытием. – utnapistim

3

Одно отличие состоит в том, что старомодная форма дает неопределенное поведение, если класс (или друг) пытается уничтожить себя. Внутри членов класса и друзей деструктор доступен, поэтому при его использовании отсутствует ошибка времени компиляции. Вместо этого вы получаете нарушение правила Единого определения. На практике это вызовет ошибку связи, но формально поведение не определено.

Удаление конструктора (или другой функции) вызывает ошибку компиляции, если функция необходима при любых обстоятельствах; и заявляет о намерении более явно, позволяя компилятору лучше диагностировать сообщения. Это особенно полезно, если функции неявно удалены из-за чего-то еще.

+0

OP означает копировать конструктор не разрушитель – ZijingWu

+1

@ZijingWu: Так он и делает. Я только что ответил на другой вопрос о деструкторах и заставил двух путаться. Однако это не влияет на ответ. –

+0

Это действительно замечательная нота, я ее поддержал. –