Программирование >>  Обобщенные обратные вызовы 

1 ... 23 24 25 [ 26 ] 27 28 29 ... 84


Разработка классов, наследование и полиморфизм

Помимо парадигмы обобщенного программирования, С++ поддерживает объектно-ориентированное проектирование и программирование. В этом разделе мы обратимся к этой более традиционной области, уделив основное внимание объектно-ориентированным возможностям С+ + .

Мы начнем с примера реального кода, в котором есть один тонкий изъян, и используем его в качестве трамплина для обзора порядка конструирования и деструкции объектов.

Затем мы обратимся к вопросам создания надежного кода, которые пересекаются с вопросами безопасности. Какая часть класса доступна из другого кода? Как осуществить утечку закрытой части класса, причем не столь важно, непреднамеренно или специально? Что такое инкапсуляция и как она соотносится с выбором прав доступа к членам? Наконец, как сделать наши классы более удобными с точки зрения управления версиями, а также с легко поддерживаемым интерфейсом, который не может быть случайно или преднамеренно разрушен в порожденных классах, что могло бы привести к неработоспособности и брешам в системе безопасности?

Итак, погрузимся в море классов и объектов...



Задача 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



1 ... 23 24 25 [ 26 ] 27 28 29 ... 84

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика