Проектируйте с учетом наследования
Никогда не надейтесь, что класс не будет использоваться в качестве базового класса. Сосредоточимся на случае с примером управляющего элемента-редактора из предыдущего правила. Я бы хотел реализовать такой элемент, наследуя одновременно от класса window и от класса string, потому что он обладает свойствами обоих. У меня ничего бы не получилось, если бы многие из функций string не были виртуальными. То есть, так как я могу делать со строкой следующее:
string str = "xxx"; // инициализировать строку значением "xxx"
str = "Абв"; // заменить предыдущее значение на "Абв"
str += "где"; // присоединяет "где" к имеющейся строке.
то хотел иметь возможность делать следующее, чтобы поместить текст как в буфер, принадлежащий управляющему элементу-редактору, так и в соответствующее окно:
class edit_control : public string
, public window
{/* ... */}
edit_control edit = "xxx";
edit = "Абв";
edit += "где";
Я бы также хотел передавать свой объект edit_control в функцию, ожидающую в качестве аргумента string, так чтобы любые изменения, которые эта функция делает в (том, что она принимает за) string, автоматически отображались и в окне управляющего элемента-редактора.
Все это не возможно, если функции, подобные operator=() и operator+=(), не виртуальные в классе string и, тем самым, не позволяющие мне менять их поведение в производном классе edit_control. Например, так как функция operator=()
класса string из листинга 7 со страницы 155 является виртуальной, то я могу сделать следующее:
class edit_control : public string
, public window
{
// ...
virtual
string operator=( const string r );
}
virtual string edit_control::operator=( const string r )
{
*(string *)this = r;
window::caption() = r; // операция разрешения видимости
// window:: просто для ясности
}
Следующей функции может быть передан или простой объект string, или объект edit_control; она не знает или ей все равно, какой конкретно:
f( string *s )
{
// ...
*s = "Новое значение" ;
}
В случае объекта string
внутренний буфер обновляется. В случае edit_control
буфер обновляется, но также модифицируется заголовок его окна.