Идиомы и стили С++ (Махмутов) - страница 8

, если потом нарисовать диалоговое окно, положить в него одну кнопку, а на OnClick повесить обработчик одного сообщения, весом в 20 тысяч строк. Ну это личное дело каждого. Я сам так делаю. На дельфях и фокспре.

А можно еще потолковать о распределенных приложениях. Или архитектурных решениях. Блин, надо же подняться как-то над WinAPI и RAS, они же и в MSDN есть. Ну ладно, будет с этим. Конец лирического отступления. Вернемся к нашим баранам, то бишь указателям.

Давайте подумаем, какой интерфейс есть у класса. Его объявление? Верно. Но не все. Интерфейс - это то, что видит клиент. А видят разные клиенты разное. Отношения дружбы, наследования, модификаторы доступа сами по себе изменяют интерфейс. Как мы можем приобрести почти неограниченный контроль над интерфейсом? Ранее рассмотренные ведущие указатели не позволяют изменять интерфейс, ибо перегруженный оператор -› действительно позволяет осуществлять доступ к настоящему интерфейсу, а значит, информация о нем должна быть доступна. Ну и не будем его перегружать. Ничего не мешает просто скопировать нужную часть его интерфейса в определение указателя, и вызывать нужные функции объекта в одноименных функциях указателя. Если нас интересует секретность, то делаем все функции не-подстановочными (то есть определяем их вне объявления класса и без модификатора inline). Вот код:

>// Это находится в заголовочном файле.

>class Cthat;

>class CPthat {

>private:

> Cthat* t; // обычный указатель на объект

>public:

> CPthat ();

> CPthat (const CPthat&);

> ~CPthat ();

> CPthat& operator=(const CPthat&);

> // Новый интерфейс - дубликат

> void funct1(void);

> void funct2(void);

>};


>// Это все содержится в cpp-файле.

>// и первое - определение указываемого объекта

>class Cthat {

> friend class CPthat;

>private:

>protected:

> Cthat();

>public:

> // Родной интерфейс.

> void funct1(void);

> void funct2(void);

>};


>//Реализация членов-функций класса указателя.

>CPthat::CPthat ():t(new Cthat) {}

>CPthat::CPthat (const CPthat& _cp):t(new Cthat(*(_cp.t))) {}

>CPthat::~CPthat (){ delete t; }

>CPthat& CPthat::operator=(const CPthat& _cp) {

> if (this != &_cp) {

>  delete t;

>  t = new Cthat(*(_cp.t));

> }

> return *this;

>}

>void CPthat::funct1(void) { t-›funct1(); }

>void CPthat::funct2(void) { t-›funct2(); }


>// Реализация членов-функций класса объекта

>Cthat::Cthat() {}

>void Cthat::funct1(void) {}

>void Cthat::funct2(void) {}

Все, приплыли. От класса указываемых объектов остался только перископ в виде class Cthat;, а более ничего. CPthat действует вместо него. Он сам стал им. Класс CPthat является классом интерфейсного указателя.