Alt linux Программирование на языке С++ в среде Qt Creator Е. Р. Алексеев, Г. Г. Злобин, Д. А. Костюк, О. В. Чеснокова, А. С. Чмыхало Москва alt linux 2015



Download 5,27 Mb.
Pdf ko'rish
bet130/193
Sana24.02.2022
Hajmi5,27 Mb.
#227496
1   ...   126   127   128   129   130   131   132   133   ...   193
Bog'liq
Book-qtC


Глава 10. Объектно-ориентированное программирование
public :
p o i n t ( i n t p1 , i n t p2 , i n t c ) ;
} ;
p o i n t : : p o i n t ( i n t p1 , i n t p2 , i n t c )
{
x=p1 ;
y=p2 ;
c o l o r=c ;
}
c l a s s v e r t e x : public p o i n t
{
i n t z ;
public :
v e r t e x ( i n t p1 , i n t p2 , i n t p3 , i n t c ) ;
} ;
v e r t e x : : v e r t e x ( i n t p1 , i n t p2 , i n t p3 , i n t c ) : p o i n t ( p1 , p2 , c )
{
z=p3 ;
}
main ( )
{
v e r t e x c1 ( 2 , 3 , 4 , 0 ) ;
}
Допускается также использовать эту краткую запись передачи параметров
родительскому конструктору, чтобы компактно проинициализировать перемен-
ные дочернего класса. Например, мы могли бы написать в предыдущем примере:
v e r t e x : : v e r t e x ( i n t p1 , i n t p2 , i n t p3 )
: p o i n t ( p1 , p2 ) , z ( p3 )
{
// z=p3 ;
}
С наследованием конструкторов класса связана ещё одна специфическая осо-
бенность: если в базовом классе есть перегруженный оператор присваивания, он
не наследуется производными классами. Если оператор присваивания был пере-
гружен в родительском классе, а в производном — нет, то присваивание объектов
производного класса не будет вызывать ошибку, однако выполняться при этом
будет не перегруженный оператор, а присваивание по умолчанию, т. е. побитовое
копирование свойств объекта.
10.4.2
Раннее и позднее связывание
Обрабатывая вызов метода какого-либо класса, компилятор сначала ищет
метод с указанным именем внутри данного класса. Если метод с таким именем
не определён внутри класса, то компилятор обращается к базовому классу и ищет
его там. Если найдёт, то подставит в точки вызова адрес метода из родительского
класса. Если не найдёт, то поднимается всё выше по иерархии наследования.
Методы, которые вызываются так, являются статическими — в том смысле,
что компилятор разбирает ссылки на них во время компиляции. Этот подход
экономит ресурсы в момент выполнения программы, однако иногда приводит к
нежелательным результатам. Рассмотрим для примера иерархию из двух клас-
сов: класса vector, представляющего собой двумерный вектор, и производный
от него класс spatial_vector, уже знакомый нам по прежним примерам. Нам
Программирование на языке С++ в среде Qt Creator


10.4. Наследование
297
будут нужны два метода у каждого из классов: метод info(), выводящий тек-
стовое сообщение и сообщающий, чему равен модуль вектора, и метод abs(),
собственно вычисляющий значение модуля. Наследование одного класса от дру-
гого в данном случае представляется вполне логичным: в производном классе
достаточно будет добавить ещё одну переменную, модифицировать конструктор
и функцию вычисления модуля.
#include 
#include 
using namespace s t d ;
c l a s s v e c t o r
{
protected :
double x , y ;
public :
v e c t o r ( double x , double y ) { this−>x=x ; this−>y=y ; }
double abs ( ) { return s q r t ( x∗x + y∗y ) ; }
void i n f o ( ) { c o u t << "Модуль вектора равен " << abs ( ) << e n d l ; }
} ;
c l a s s s p a t i a l _ v e c t o r : public v e c t o r
{
protected :
double z ;
public :
s p a t i a l _ v e c t o r ( double x , double y , double z ) ;
double abs ( ) { return s q r t ( x∗x + y∗y + z ∗ z ) ; }
} ;
s p a t i a l _ v e c t o r : : s p a t i a l _ v e c t o r ( double x , double y , double z ) : v e c t o r ( x , y )
{
this
−>z=z ;
}
main ( )
{
c o u t << "Создаём вектор на плоскости с координатами 1,2\ n " ;
v e c t o r a ( 1 , 2 ) ;
a . i n f o ( ) ;
c o u t << "Создаём пространственный вектор с координатами 1,2,3\ n " ;
s p a t i a l _ v e c t o r b ( 1 , 2 , 3 ) ;
b . i n f o ( ) ;
}
В действительности же данный код генерирует весьма странный результат:
Создаём вектор на плоскости с координатами 1,2
Модуль вектора равен 2.23607
Создаём пространственный вектор с координатами 1,2,3
Модуль вектора равен 2.23607
Мы корректно переопределили метод abs() в производном классе (можно легко
в этом убедиться, вызвав его непосредственно), однако для производного класса
функция info() выдала явно неверное значение, не посчитав в модуле третью
координату. Проблема в том, что родительский метод info() «не знает», что
функция abs() переопределена в классе-потомке.
Для того чтобы это стало возможным нужен специальный механизм, и в язы-
ке C++ это — позднее связывание, реализующее механизм виртуальных методов.
Виртуальные методы реализуют полиморфизм.
Виртуальный метод — это метод, который, будучи описан в потомках,
замещает собой соответствующий метод везде, даже в методах, описанных
для предка, если он вызывается для потомка.
© 2015 Алексеев Е. Р., Злобин Г. Г., Костюк Д. А., Чеснокова О. В., Чмыхало А. С.


298
Download 5,27 Mb.

Do'stlaringiz bilan baham:
1   ...   126   127   128   129   130   131   132   133   ...   193




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish