• • Пример #include















• • Пример #include
Наследование (2). • A! • B! • b=5 • a=0 // «а» из секции «private» здесь изменить нельзя 2
Защищенные члены класса. • class С{ • int x; //закрыто, “private” • public: • С(); • void Func 1(int); //открыто • protected: • float y; // открыто только • char* Func 2(int, float); // для потомков • int Get. X(){return x; } • }; • class CT: public C{ • …………… • }; 3
Передача аргументов в базовый класс. • class A{ • int x 1, x 2; • public: • A(int ax 1, int ax 2){x 1=ax 1; x 2=ax 2; } //конструктор • . . . • }; • class B: public A{ • int y; • B(int xx 1, int xx 2, int yy): A(xx 1, xx 2){y=yy; } //конструктор • . . . • }; • //вызов (инициализация) • B b 1(1, 2, 3); 4
Конструкторы с инициализацией по умолчанию в иерархии классов. • #include
Конструкторы с инициализацией по умолчанию в иерархии классов. • #include
Конструкторы с инициализацией по умолчанию в иерархии классов (2). • Мог ли базовый класс иметь конструктор по умолчанию? Да, но реализовать их можно только при создании базового класса • • A(int ax 1=33, int ax 2=60){x 1=ax 1; x 2=ax 2; } • . . . • A a; • cout<
Конструкторы с инициализацией по умолчанию в иерархии классов (3). • Если инициализация данных базового класса по умолчанию устраивает пользователя, то в конструкторе класса B можно не вызывать конструктор класса A: • • class B: public A{ • int y; • public: • B(int ay=0){y=ay; } • }; При создании объекта B b(25); или B b; 8
Конструкторы с инициализацией по умолчанию в иерархии классов (4). • Если умолчание в базовом классе не устраивает и в производном классе инициализировать нечего, тогда конструктор будут пустым • • class B: public A{ • int y; • public: • B(int ax 1, int ax 2, int ax 3): A(ax 1, ax 2, ax 3){}; • Возможно, не все переменные нужно инициализировать через параметр (а часть - по умолчанию. • • B(int ax 1): A(ax 1){}; • Возможны варианты. 9
• • #include
• • #include
Множественное наследование. • Наследование, при котором производный класс, наследующий возможности не одного, а нескольких классов, называется множественным. Синтаксис множественного наследования выглядит следующим образом: • class A{ • . . . A B • }; • class B{ C • . . . • }; • class C: public A, public B{ • . . . • }; • Здесь С может обратиться к любым public и protected членам базовых классов, private члены базовых классов производному классу недоступны. • При создании объекта производного класса сначала конструируются (вызываются конструкторы) базовых классов в порядке их перечисления в объявлении производного класса и лишь после этого составляется объект производного класса. 12
Виртуальные классы. • class A{ • protected: A • int x; • . . . • }; B C • class B: public A{ • . . . • }; D • class C: public A{ • . . . • }; • class D: public B, public C{ • . . . • }; • • Здесь переменная x, являющаяся членом класса A, будет присутствовать в объекте класса D в двух экземплярах. Для компилятора это не ошибка, но при обращении к переменной x из производных классов придется ее однозначно специфицировать (использовать оператор разрешения видимости): 13
Виртуальные классы (2). • class D: public B, public C{ • public: • int Get. X(){return x; } // Недопустимо. Неясно какое из двух x выбрать • int Get. X(){return B: : x; } // Допустимо. x берется из B • int Set. X(int a) {C: : x=a; } // Допустимо. x берется из C • . . . • }; • 14
Виртуальные классы (3). • Чтобы не допустить появления нескольких экземпляров одной и той же переменной, надо базовый класс объявить виртуальным При объявлении классов- потомков: • • class A{ • protected: • int x; • . . . • }; • class B: public virtual A{ • . . . • }; • class C: public virtual A{ • . . . • }; • class D: public B, public C{ • public: • int Get. X(){return x; } // теперь эта переменная - одна • }; • Теперь допустимо обращаться к переменной x просто по имени, т. к. в объекте класса D она присутствует в единственном экземпляре. • • Можно оставить спецификацию В: : х или С: : х, но это излишне. 15

