Страница 29 из 74 114. Используйте структуры только тогда, когда все данные открытые и нет функций-членов.
Это правило является вариантом принципа "если это похоже на С, то должно и действовать как С". Используйте структуры, только если вы делаете что-то в стиле С. Следует также избегать наследования от структуры. Даже если мне многое не удалось изложить четко, надеюсь, что я прояснил смысл тезиса "закрытые данные или никакие". Зная о проблемах с прямым доступом к открытым данным, вы можете понять, почему следующее не является очень хорошей идеей: typedef struct tagSIZE // Существующее определение из заголовочного файла С { LONG cx; LONG cy; } SIZE; class CSize : public SIZE // Определение в файле С++ { // ... } Я видел определения классов, подобные следующему, где требуется доступ к полям cx и cy базового класса через указатель производного класса для того, чтобы определить соответствующее им значение третьей координаты - высоты. Например: CSize some_size; some_size.cy; // тьфу! Вы должны иметь возможность написать: some_size.height();У предшествующего кода есть другая, более трудно уловимая проблема. Наследование от существующей структуры С часто выполняется программистом, который верит, что сможет передать объект С++ в существующую функцию С. То есть программист полагает, что раз наследование фактически добавляет поля к базовому классу, то производный класс в буквальном смысле будет расположен точно так же, как и базовый класс, но с присоединением нескольких дополнительных полей. Однако, это может и не быть правдой. Если производный класс добавляет, например, виртуальную функцию, то в базовый класс может быть добавлен указатель на таблицу виртуальных функций. Аналогично, если производный класс использует множественное наследование одновременно от структуры С и чего-то еще, то нет никакой гарантии, что структура С будет на верху. |