Skip to content

Conversation

@Maksimenko-Mikhail
Copy link

No description provided.

@Maksimenko-Mikhail Maksimenko-Mikhail changed the title raii delegating constructor added cpp-notes fixes Oct 21, 2023
Аналогично, *вниз по иерархии* (от базового к наследуемому) можно кастовать только тогда, когда совпадает динамический тип. Иначе UB.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`.
- `const_cast`. Снимает модификаторы `const` и `volatile`. Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB, так как с помощью `reintepret_cast` очень просто нарушить `strict aliasing rule`. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`. Но как правило `reintepret_cast<T2*>(T1*)` работает как `static_cast<T2*>(static_cast<void*>(T1*))`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вообще-то reinterpret_cast из указателя в указатель именно так и определён в стандарте, не надо обращаться ни к каким поставщикам компиляторов (implementation-defined другие версии reinterpret_cast'а, которые здесь не упомянуты, например из указателя в число)

Аналогично, *вниз по иерархии* (от базового к наследуемому) можно кастовать только тогда, когда совпадает динамический тип. Иначе UB.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`.
- `const_cast`. Снимает модификаторы `const` и `volatile`. Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB, так как с помощью `reintepret_cast` очень просто нарушить `strict aliasing rule`. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`. Но как правило `reintepret_cast<T2*>(T1*)` работает как `static_cast<T2*>(static_cast<void*>(T1*))`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

почему strict aliasing rule отформатирован как код?

Аналогично, *вниз по иерархии* (от базового к наследуемому) можно кастовать только тогда, когда совпадает динамический тип. Иначе UB.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`.
- `const_cast`. Снимает модификаторы `const` и `volatile`. Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB, так как с помощью `reintepret_cast` очень просто нарушить `strict aliasing rule`. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`. Но как правило `reintepret_cast<T2*>(T1*)` работает как `static_cast<T2*>(static_cast<void*>(T1*))`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

после "Но как правило" должна быть запятая (если это выражение останется после изменений)

- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`.
- `const_cast`. Снимает модификаторы `const` и `volatile`. Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
- `reinterpret_cast` — всё зашкварное из C-style cast'а. Перевод указателей несвязанных друг с другом типов, указателей в число и обратно. Простой и эффективный способ получить UB, так как с помощью `reintepret_cast` очень просто нарушить `strict aliasing rule`. В стандарте так и написано, это implementation-defined cast. Обратитесь к поставщику вашего компилятора, чтобы понять, как у вас работает `reinterpret_cast`. Но как правило `reintepret_cast<T2*>(T1*)` работает как `static_cast<T2*>(static_cast<void*>(T1*))`.
- `const_cast`. Снимает модификаторы `const` и `volatile` (с помощью `const_cast` можно также навешивать `const`, но это не имеет особого смысла). Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

дописанное в скобках относится не только к const, не вижу смысла уточнять

Suggested change
- `const_cast`. Снимает модификаторы `const` и `volatile` (с помощью `const_cast` можно также навешивать `const`, но это не имеет особого смысла). Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.
- `const_cast`. Снимает модификаторы `const` и `volatile` (может и навешивать их, но это не имеет особого смысла). Чаще всего это делать не надо, но иногда бывает нужно всё-таки. В стародавние времена, когда `const`'ов не было, были функции, принимавшие указатель. Неконстантный, хотя не меняли его содержимое. И вот если вы хотите использовать эту функцию, вы можете снять `const` с указателя. А вообще правило вот какое: **если изначальный объект был `const`, снимать с него `const` ни в коем случае нельзя (UB). Если изначальный объект константным не был, а потом вы сначала навесили `const`, а потом сняли, то всё хорошо**.

### `protected`.
Представим, что мы пишем виджет на основе QT. Там есть базовый виджет, у которого есть операции, что делать в случае нажатия мышки, в случае перемещения колёсика и прочее подобное. Вам всё это нужно переопределить. В таком случае в базовом виджете используется ключевое слово `protected`. Оно для похожих случаев и было создано, лол. Это модификатор доступа, дающий доступ только дочерним классам и себе.

Стоит отметить, что `protected` предоставляет доступ только внутри дочернего класса, то есть если есть функция в `derived` классе и мы передаем в нее объект типа `base`, то обратиться к `protected` полям и функциям `base` мы все равно не сможем.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я понимаю, что ты хочешь донести, но сформулировано непонятно, что значит "внутри"? вопрос актуален даже если забить на то, что у derived тоже могут быть наследники, а если не забивать, стоит сформулировать ещё точнее

Comment on lines +495 to 496
Стоит отметить, что `protected` предоставляет доступ только внутри дочернего класса, то есть если есть функция в `derived` классе и мы передаем в нее объект типа `base`, то обратиться к `protected` полям и функциям `base` мы все равно не сможем.
С ним, правда, есть вопрос. Если метод не ломает инвариант, почему он не `public`, а если ломает, то хотим ли мы давать доступ дочерним классам. Тем не менее, эти вопросы не риторические, если вы нашли на них ответ — делайте `protected`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

стоит разделить эти абзацы

};
```

В данном примере, если в публичном конструкторе будет выброшено исключение, то утечек данных не произойдет, так как приватный конструктор уже закончит свое исполнение к моменту выброса исключения и будет вызван деструктор, который высвободит выделенные ресурсы.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

пропущена запятая:

Suggested change
В данном примере, если в публичном конструкторе будет выброшено исключение, то утечек данных не произойдет, так как приватный конструктор уже закончит свое исполнение к моменту выброса исключения и будет вызван деструктор, который высвободит выделенные ресурсы.
В данном примере, если в публичном конструкторе будет выброшено исключение, то утечек данных не произойдет, так как приватный конструктор уже закончит свое исполнение к моменту выброса исключения, и будет вызван деструктор, который высвободит выделенные ресурсы.

};
```

В данном примере, если в публичном конструкторе будет выброшено исключение, то утечек данных не произойдет, так как приватный конструктор уже закончит свое исполнение к моменту выброса исключения и будет вызван деструктор, который высвободит выделенные ресурсы.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а где-то написано о том, почему достаточно срабатывания приватного конструктора? если нет, лучше явно написать

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants