UR.ANUS
Идиомы и стили С++
вернуться

Makhmutov Albert

Шрифт:

Напоследок прописная истина для тех, кто не знает: общие определения полиморфизма, наследования, инкапсуляции, понимание перегрузки операторов, перегрузки и переопределения функций, абстрактных классов, виртуальных и чистых виртуальных функций, конструкторов и деструкторов КРИТИЧЕСКИ ВАЖНЫ ПРИ ПОИСКЕ РАБОТЫ ЗА БУГРОМ!!! Если Вы запнетесь хоть на одном из этих терминов, то Ваш интервьюер никогда Вам больше не позвонит, а если он еще и работает на крупную фирму, то Вас занесут в базу данных как никчемного ламера, и с ней будут сверяться десятки рекрутеров по всем Юнидос Эстадос. Вот так.

Шаг 11 - Нетривиальное конструирование объектов.

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

CClass {

protected:

 CClass {}

};

А если Вы еще хотите так же и запретить наследование, то конструкторы перемещаются в закрытую часть объявления:

CClass {

private:

 CClass {}

};

Но как же тогда их вообще создавать, если их конструкторы недоступны? Да ясно как, ведь сам вопрос неверен: конструкторы не недоступны, они доступны, да только не для всех. Мы же как-то уже замечали, что класс по определению имеет несколько интерфейсов для разных клиентов, и помним, что самый полный, самый неограниченный интерфейс класс имеет для себя и для своих друзей. Следовательно, производящая функция-член класса или дружественная функция может свободно штамповать экземпляры класса и размещать где угодно, кроме стека; функция-член класса должна быть кроме того статической (то есть независимой от экземпляров), иначе в ней нет смысла.

// Вариант 1: производящая функция-член.

CClass {

public:

 static CClass* factory (void);

private:

 CClass {}

};

CClass* CClass::factory(void) { return new CClass; }

// Где-то в коде

CClass* cc = CClass::factory(void);

// Вариант 2. Дружественная функция.

CClass {

 friend CClass* factory (void);

private:

 CClass {}

};

// Дружественная Функция, создающая экземпляры класса.

CClass* factory (void) {

 return new CClass;

}

// Где-то в коде

CClass* cc = factory(void);

Вы видите, что разницы между двумя вариантами практически нет? Единственно, что дружественная функция лежит вне области видимости класса. Но она фактически является элементом его интерфейса! Именно это наблюдение позволило Мейерсу сделать несколько неожиданный вывод: дружественные функции могут улучшать инкапсуляцию класса! Не знаю, как для Вас, но мне пришлось прочитать его статью дважды, а потом еще найти перевод на русский язык, потому как сразу это не в голове не уложилось. Подробности читайте в "С++ Journal", апрель 2000 года.

Желая продолжить изыскания в области ограничения конструирования, зададим вопрос: А можно ли совсем запретить конструирование экземпляров класса, даже для друзей и для статических функций? Ответ: Да. Можно. Нужно сделать как минимум одну функцию чистой виртуальной (pure virtual). Для этого есть специальный синтаксис:

virtual void f(void)=0;

В этом случае компилятор не может создать для класса виртуальную таблицу, и соответственно не может создать экземпляр.

Вернемся опять к статической функции. Статическую функцию класса можно вызвать двумя способами - указав либо имя класса, либо через экземпляр класса.

CClass* cc1 = CClass::factory(void);

CClass* cc2 = cc1-›factory(void); // Вызов производящей функции

// Не знаю, откуда мы его берем, но это стековый экземпляр

CClass cc3;

CClass* cc4 = cc3.factory(void); // Еще один вызов производящей функции

Тут-то и делается самый прикол. Мы делаем виртуальный конструктор: виртуальную производящую функцию:

CClass {

public:

 // Теперь виртуальная, а не статическая.

 virtual CClass* factory (void);

 // Конструктор делаем для простоты открытым,

 // поскольку все-таки нам нужен

 // базовый способ получения экземпляров

 CClass {}

};

  • Читать дальше
  • 1
  • ...
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • ...

UR.ANUS - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • support@anus.bid