Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
[ Диск ]
/* InheritanceExample — пример наследования, при */
/* котором конструктор наследника */
/* передаёт информацию конструктору базового класса */
_________________
234 стр. Часть 4. Наследование
#include
#include
#include
#include
using namespace std ;
/* Advisor — пустой класс */
class Advisor { } ;
const int MAXNAMESIZE = 40 ;
class Student
{
public :
Student( char *pName = "no name" )
: average( 0.0 ) , semesterHours( 0 )
{
strncpy( name , pName , MAXNAMESIZE ) ;
name[ MAXNAMESIZE - 1 ] = '\0' ;
cout << "Конструктор Student "
<< name
<< endl ;
}
void addCourse( int hours , float grade )
{
cout << "Добавляем оценку для " << name << endl ;
average = ( semesterHours * average + grade ) ;
semesterHours += hours ;
average = average / semesterHours ;
}
int hours( ) { return semesterHours ; }
float gpa( ) { return average ; }
protected :
char name[ MAXNAMESIZE ] ;
int semesterHours ;
float average ;
} ;
class GraduateStudent : public Student
{
public :
GraduateStudent( char *pName , Advisor & adv , float qG = 0.0 )
: Student( pName ), advisor( adv ) , qualifierGrade(qG)
{
cout << "Конструктор GraduateStudent "
<< pName
<< endl ;
}
float qualifier( ) { return qualifierGrade ; }
protected :
Advisor advisor ;
_________________
235 стр. Глава 20. Наследование классов
float qualifierGrade ;
} ;
int main( int nNumberofArgs , char* pszArgs[ ] )
{
/* печать кириллицы, если Вы не установите программки gccrus.exe и g++rus.exe */
setlocale ( LC_ALL ,".1251" ) ;
Advisor advisor ;
/* Создание двух типов студентов */
Student llu( "Су N Sense" ) ;
GraduateStudent gs( "Matt Madox" , advisor , 1.5 ) ;
/* Добавляем им оценки */
llu.addCourse( 3 , 2.5 ) ;
gs.addCourse( 3 , 3.0 ) ;
// Выводим их
cout << "Оценка Matt = "
<< gs.qualifier( )
<< endl ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
В этой программе продемонстрировано создание и использование двух объектов — Student и GraduateStudent . Вывод программы выглядит следующим образом.
Конструктор Student Су N Sense
Конструктор Student Matt Madox
Конструктор GraduateStudent Matt Madox
Добавляем оценку для Су N Sense
Добавляем оценку для Matt Madox
Оценка Matt = 1.5
Press any key to continue...
Использование подкласса...236
Класс Student определён как обычно. Определение класса GraduateStudent несколько отличается — наличием после имени класса двоеточия с последующим public Student . Тем самым класс GraduateStudent объявляется как подкласс класса Student .
«Ключевое словоpublic говорит о том, что может быть наследованиеprotected , а такжеprivate — но эти вопросы лежат за пределами данной книги.»
[ Советы ]
Программисты любят вводить новые термины и придавать новые значения старым. Вот набор тождественных высказываний, описывающих одно и то же отношение между классами:
■■■
■ GraduateStudent — подкласс Student;
■ Student — базовый, или родительский класс для GraduateStudent;
■ GraduateStudent наследует Student;
■ GraduateStudent расширяет Student.
■■■
_________________
236 стр. Часть 4. Наследование
В качестве подкласса Student класс GraduateStudent наследует все его члены. Например, GraduateStudent имеет член name , хотя он объявлен в базовом классе. Однако подкласс может добавлять собственные члены, например, qualifierGrade.
Функция main( ) объявляет два объекта, типа Student и GraduateStudent , после чего вызывает функцию addCourse( ) для каждого из них, а потом — функцию qualifier( ) , которая имеется только у подкласса.
Конструирование подкласса...237
Хотя подкласс и имеет доступ к защищённым членам базового класса, а значит, может инициализировать их, было бы хорошо, если бы базовый класс всё же конструировал сам себя. В действительности так и происходит.
Перед тем как управление получает код, стоящий за открывающей фигурной скобкой класса GraduateStudent , оно передаётся конструктору по умолчанию класса Student ( поскольку другой конструктор не был указан ). Если бы класс Student был наследником другого класса, например Person , то конструктор этого класса вызывался бы до передачи управления конструктору Student . Подобно небоскребу, объект строится, начиная с "фундаментального" уровня в соответствии со структурой наследования классов и вызывая конструкторы всех классов, составляющих данный.
Как и в случае с объектами-членами, вам может понадобиться передавать аргументы конструктору базового класса. Это делается почти так же, как и изученная ранее передача аргументов конструктору объекта-члена ( смотрите приведённый ниже пример ).
GraduateStudent( char *pName , Advisor &adv , float qG=0.0 )
:Student( pName ) , advisor( adv ) , qualifierGrade(qG)
{
/* Код конструктора */
}
В этом примере конструктор класса GraduateStudent вызывает конструктор Student , передавая ему аргумент pName . Базовый класс конструируется до любых объектов-членов, а значит, конструктор класса Student вызывается перед конструктором Advisor . И только после конструктора члена Advisor начинает работу конструктор GraduateStudent.
В случае, когда в подклассе не указан явный вызов конструктора базового класса, вызывается конструктор по умолчанию базового класса. Таким образом, в следующем коде базовый класс Pig конструируется до членов LittlePig , несмотря на то, что конструктор LittlePig не делает явного вызова конструктора Pig .
class Pig
{
public :
Pig( ) : pHouse( 0 ) { }
protected :
House* pHouse ;
} ;
class LittlePig : public Pig
{
public :
LittlePig( float volStraw , int numSticks , int numBricks )
: straw( volStraw ) , sticks( numSticks ) , bricks( numBricks )
{ }
protected :
float straw ;
int sticks ;
int bricks ;
} ;
Аналогично, автоматически вызывается копирующий конструктор базового класса.
_________________
237 стр. Глава 20. Наследование классов
Деструкция подкласса...238
Следуя правилу о том, что деструкторы вызываются в порядке, обратном вызову конструкторов, первым вызывается деструктор GraduateStudent . После того как он выполнит свою работу, управление передаётся деструктору класса Advisor, а затем деструктору Student . Если бы Student был наследником класса Person , его деструктор получил бы управление после деструктора Student .
И это логично. Блок памяти сначала преобразуется в объект Student , а уже затем конструктор для GraduateStudent превращает этого студента в аспиранта. Деструктор же просто выполняет этот процесс в обратном направлении.
Читать дальшеИнтервал:
Закладка: