Побывал на тренинге Steve Dewhurst‘а “C++ Common Knowledge”. У меня уже давно есть его книга:
и в целом конкретно этот тренинг посвящен темам из нее.
Очень прикольный дядька. Нескучно, разбавлено подколами аудитории и шутками типа что ребята из Boost’a не иначе как курят шаблоны и т.д. Мне очень понравилось.
Стив сказал, что С++ - это практически все, что делал и делает в жизни. Писал компиляторы, утилиты, разбирался в стандартах, а сейчас вот дает тренинги.
Не могу сказать, что я узнал что-то особенно новое — это было бы странно, так как его книжку (см. выше) читал от корки до корки и периодически к ней возвращаюсь. Хотя, пожалуй, одна мысль меня зацепила: правильное написание конструктора копирования или оператора присваивания для класса, в иерархии которого есть виртуальный базовый класс с данными является весьма запутанной задачей. Тут однозначно нарушается принцип логической независимости уровней иерархии наследования, так как надо точно знать, от каких классов ты унаследован и как их правильно инициализировать при множественном наследовании.
Рекомендация такая: сначала задаешь себе вопрос: а нужно ли мне тут множественное наследование? а нужно ли мне виртуальное множественное наследование?? а нужно ли мне виртуальное множественное наследование с данными в базовом виртуальном классе??? И даже после долгого раздумья лучше сказать “нет”. Лично я не имею ничего против множественного наследования. Но мне не очень нравится как это сделано в С++. И мне не очень нравится как это сделано в Java. Мне очень нравится, как сделано в Go. А именно: в Go полностью разнесены понятия структур данных и интерфейсов. Структуры данных не могут быть унаследованы. Они могут только реализовывать интерфейсы. А наследовать можно только интерфейсы. Поэтому в принципе нельзя при наследовании подцепить чужие данные, а только методы. А нет данных, не и проблемы их инициализации.
Итак, могу просто собрать общие рекомендации от Стива:
if
и case
std::vector
гарантирует линейное размещение элементов, то можно смешивать “старый” код, работающий с указателями, с использованием контейнеров)static_cast
, const_cast
и т.д.), так как они длинные, их нудно набивать и они уродуют вид программы - в общем, все, что нужно для минимизации их наличия