|
Программирование >> Обобщенные обратные вызовы
Разработка классов, наследование и полиморфизм Помимо парадигмы обобщенного программирования, С++ поддерживает объектно-ориентированное проектирование и программирование. В этом разделе мы обратимся к этой более традиционной области, уделив основное внимание объектно-ориентированным возможностям С+ + . Мы начнем с примера реального кода, в котором есть один тонкий изъян, и используем его в качестве трамплина для обзора порядка конструирования и деструкции объектов. Затем мы обратимся к вопросам создания надежного кода, которые пересекаются с вопросами безопасности. Какая часть класса доступна из другого кода? Как осуществить утечку закрытой части класса, причем не столь важно, непреднамеренно или специально? Что такое инкапсуляция и как она соотносится с выбором прав доступа к членам? Наконец, как сделать наши классы более удобными с точки зрения управления версиями, а также с легко поддерживаемым интерфейсом, который не может быть случайно или преднамеренно разрушен в порожденных классах, что могло бы привести к неработоспособности и брешам в системе безопасности? Итак, погрузимся в море классов и объектов... Задача 14. К порядку! Сложность: 2 у программистов, изучающих С++, часто возникают неправильные представления о том, что можно и чего нельзя делать в С++. В приведенном ниже примере, представленном Яном Кристианом ван Винклем, студенты допускают фундаментальную ошибку - но многие компиляторы пропускают ее даже без предупреждений. Вопрос для новичка 1. Приведенный далее код был действительно написан студентом, изучающим С+ + , и компилятор, которым он пользовался, не выдал никакого предупреждения (более того, так поступает целый ряд популярных компиляторов). Так что же не верно в приведенном коде и почему? #include <string> using namespace std; class A { public: AC const strings, s ) { /* ... */ } string f() { return hello, world ; } class В : public A { public: b() : A( s = fC) ) {} private: stri ng s; i nt mai nC) { В b; Вопрос для профессионала 2. В каком порядке выполняется инициализация различных частей создаваемого объекта класса в С+ + ? Будьте предельно точны в своем ответе. Укажите порядок инициализации различных частей объекта класса х в следующем примере. class Bl { }; class VI : public Bl { }; class Dl : vi rtual public VI { }; class b2 { }; class B3 { }; class v2 : public Bl, public b2 { }; class d2 : public вЗ, vi rtual public V2 { }; class Ml { }; class m2 { }; class X : public Dl, public d2 { Ml ml ; m2 m2 ; Решение 1. ...Так что же не верно в приведенном коде и почему? пример 14-1 во : АС S = fО ) {} ... в указанной строке проявляются две взаимосвязанные проблемы, относящиеся ко времени жизни объекта и его использованию до создания. Обратите внимание, что выражение s = f () является аргументом конструктора подобьекта базового класса А и, следовательно, выполняется до того, как будет построен базовый подобъскт А (или любая часть объекта в). Во-первых, .эта строка кода пытается использовать еще не существующий базовый подобъект А. Компилятор студента, написавшего этот код, не замечал некорректного использования А: :f, состоящего в том, что функция f вызывается для подобъекта д, который еще не сконструирован. Компилятор не обязан диагностировать такие ошибки; однако это то, что называется качеством реализации , и достаточно хороший компилятор вполне мог бы заметить данную ошибку. Во-вторых, здесь же выполняется попытка использовать член s подобъекта, который еше не существует, т.е. применить оператор присваивания к строке-члену объекта, конструирование которого еще не завершено. 2. В каком порядке выполняется инициализация различных частей создаваемого объекта класса в С++? Будьте предельно точны в своем ответе. Порядок инициализации определяется рекурсивным применением следующего набора правил. Сначала конструктор последнего производного класса вызывает конструкторы подобъектов виртуальных базовых классов. Инициализация виртуальных базовых классов выполняется в глубину, в порядке слева направо. Затем конструируются подобъекты н с посредстве иных базовых классов в порядке их объявления в определении класса. После этого конструируются (нестатические) подобъекты-члены в порядке их объявления в определении класса. И наконец, выполняется тело конструктора. В качестве примера рассмотрим приведенный в задаче код. Вид наследования (открытое, закрытое или защищенное) не влияет на порядок инициализации, так что все наследование показано мной как открытое. Укажите порядок инициализации различных частей объекта класса X в следующем примере. пример 14-2 class в1 { }; class VI : public Bl { }; class Dl : virtual public vl { }; class 82 { }; class b3 { }; class V2 : public Bl, public в2 { }; class d2 : virtual pub Ii с v2, public B3 { }; class Ml { }; class M2 { }; class X : public Dl, public D2 { Ml ml ; M2 m2 ; Иерархия наследования имеет структуру, показанную на рис. 14.1. Задача 14. К порядку! 97
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |