Правила программирования на Си и Си++



   Подробности купить пластиковые окна цены тут.        

135. Суперобложки на Си++ для существующих интерфейсов редко хорошо работают


Как правило, переменная должна инициализироваться во время объявления. Разделение инициализации и объявления иногда обусловливается плохим проектированием в программе, которая написана не вами, как в следующем фрагменте, написанном для выполнения совместно с библиотекой MFC Microsoft:

f( CWnd *win ) // CWnd - это окно

{

   // Следующая строка загружает "буфер" с шапкой окна

   // (текстом в строке заголовка)

   char buf[80];      /* = */

   win->GetWindowText(buf, sizeof(buf));

   // ...

}

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

вместить объявление и инициализацию в одной и той же строке.

Здесь имеется несколько проблем, первая из которых заключается в плохом проектировании класса CWnd

(представляющем окно). Так как у окна есть "текстовый" атрибут, хранящий заголовок, то вы должны иметь возможность доступа к этому атрибуту подобным образом:

CString caption = win->caption();

и вы должны иметь возможность модифицировать этот атрибут так:

win->caption() = "новое содержание";

но вы не можете сделать этого в текущей реализации. Главная проблема состоит в том, библиотека MFC не была спроектирована в объектно-ориентированном духе — т.е. начать с объектов, затем выбрать, какие сообщения передавать между ними и какими атрибутами их наделить. Вместо этого проектировщики Microsoft начали от существующего процедурного интерфейса (API Си —

интерфейса прикладного программирования для Windows на Си) и добавили к нему суперобложку на Си++, тем самым увековечив все проблемы существующего интерфейса. Так как в API Си была функция с именем GetWindowText(), то проектировщики беззаботно сымитировали такой вызов при помощи функции-члена в своей оболочке CWnd. Они поставили заплату на интерфейс при помощи следующего вызова:

CString str;

win->GetWindowText( str );

но это — не решение по двум причинам: по-прежнему требуется инициализация в два приема, и аргумент является ссылкой на результат.




Содержание  Назад  Вперед