Правила программирования на С и С++. Главы 7-8
Страница 26. Проектируйте с учетом наследования


 

112. Проектируйте с учетом наследования.

Никогда не надейтесь, что класс не будет использоваться в качестве базового класса. Сосредоточимся на случае с примером управляющего элемента-редактора из предыдущего правила. Я бы хотел реализовать такой элемент, наследуя одновременно от класса 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 со страницы 111 является виртуальной, то я могу сделать следующее:

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 буфер обновляется, но также модифицируется заголовок его окна.

 
« Предыдущая статья   Следующая статья »