explicit c зачем нужен

explicit в деталях

Если спросить C++-программиста о значении ключевого слова explicit, большинство ответит, что это ключевое слово ставится перед объявлением конструктора с одним параметром (или с большим числом параметров, но когда все параметры, начиная со второго, имеют значения по умолчанию) и предотвращает неявное преобразование типов при инициализации.

В старом добром C++03 сценарии применения ключевого слова на этом заканчивались, однако, начиная с C++11, область применения explicit расширилась: теперь оно имеет смысл не только в конструкторах с одним параметром, и даже не только в конструкторах.

В 2011 году в Стандарт добавили универсальную инициализацию (uniform initialization), которая должна навести порядок в зоопарке способов инициализации объектов, доставшемся C++ в наследство от языка C. Я не буду здесь подробно рассказывать про универсальную инициализацию, на эту тему есть множество подробных статей, их несложно найти по ключевым словам. В двух словах: объекты предлагается инициализировать при помощи фигурных скобок, по сути это расширение т.н. агрегатной инициализации (aggregate initialization), унаследованной ещё со времён C.

С появлением универсальной инициализации explicit обрёл смысл для конструкторов с 0,2,3 и более параметров:

Помимо этого, начиная с C++11 ключевое слово explicit может также применяться к операторам преобразования типа, также запрещая их неявный вызов:

В заключение хочется порекомендовать использовать универсальную инициализацию в любом новом коде на C++, а также явно объявлять конструкторы explicit всегда, кроме случаев, когда неявное преобразование семантически оправдано.

Источник

Принцип работы конструкторов с ключевым словом explicit понял. В чем заключается практическое применение?

Если мы хотим «огородиться» от нежелательных (нам) преобразований, то:

Результат будет: «A(int)» Если мы пометим оба конструктора explicit в целях «ограждения», то при: A a(‘x’); мы все равно получим результат выше. Все равно произойдет ненужное (нам) преобразование.

explicit c зачем нужен. Смотреть фото explicit c зачем нужен. Смотреть картинку explicit c зачем нужен. Картинка про explicit c зачем нужен. Фото explicit c зачем нужен

3 ответа 3

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

Тогда вызов f(5) тоже будет вполне допустимой конструкцией. Вряд ли это кому-то нужно. Как и

explicit c зачем нужен. Смотреть фото explicit c зачем нужен. Смотреть картинку explicit c зачем нужен. Картинка про explicit c зачем нужен. Фото explicit c зачем нужен

Конструктор без explicit позволяет осуществлять неявное преобразование типа аргумента в тип класса, которому принадлежит конструктор.

Если мы пометим оба конструктора explicit в целях «ограждения», то при: A a(‘x’); мы все равно получим результат выше.

Правильно, потому что запись A a(‘x’); есть direct-initialization, для которой как раз подходит explicit конструктор. Т.е. здесь есть неявное преобразование типа char в тип int для аргумента, но вот преобразование в тип A уже вполне явное.

В чем заключается практическое применение?

Дополнительно хочу отметить, что до c++11 explicit актуально было делать только конструкторы, которые можно вызывать с одним аргументом. С появлением uniform initialization это стало актуальным и для конструкторов, требующих нескольких обязательных аргументов. Например:

Кстати, хотя в вопросе упомянуты только конструкторы, explicit может быть применен также и к операторам преобразования (начиная с c++11 ):

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *