Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#endif
#ifndef представляет собой директиву препроцессора, такую же, как и, например, директива #include . Данная директива гласит, что включать следующие за ней строки следует только в том случае, когда её аргумент _STUDENT_ не определён. При первом включении файла _STUDENT_ не определён, но тут же определяется директивой #define_STUDENT_ . Это приводит к тому, что включение файла Student.h в программу будет выполнено только один раз, независимо от того, сколько директив #include встретится в программе.
_________________
260 стр. Часть 4. Наследование
Определение пространства имён...261
Следующая особенность программы состоит в том, что класс Student определён в пространстве имён Schools .
Пространство имён представляет собой множество тесно связанных классов, в чём-то логически подобных друг другу. В нашем случае я хочу поместить все создаваемые классы, представляющие студентов, аспирантов и т.п. в одно пространство имён Schools .
Классы, составляющие пространство имён Schools , выглядят как члены одной семьи. Один класс из пространства имён может обращаться к другому классу из этого же пространства имён непосредственно, в то время как внешние классы должны явно указывать при обращении пространство имён.
«Ещё одной причиной для использования пространств имён служат так называемые "коллизии имён", которых надо избегать. Например, классGrade из пространства имёнSchools никак не влияет на возможность использования этого же имени для класса в пространстве имёнFoodProduction .»
[ Советы ]
Реализация класса student...261
Реализация класса Student помещена мною в файл Student.срр .
/* Student — реализация методов класса Student */
#include
#include
#include
#include
#include "student.h"
namespace Schools
{
Student::Student( char* pszNameArg , int nIDArg )
: nID( nIDArg )
{
pszName = new char[ strlen( pszNameArg ) + 1 ] ;
strcpy( pszName , pszNameArg ) ;
}
/* display — возвращает описание студента */
char* Student::display( )
{
/* Копируем имя студента в блок памяти в куче, который возвращается вызывающей функции */
char* pReturn = new char[ strlen( pszName ) + 1 ] ;
strcpy( pReturn , pszName ) ;
return pReturn ;
}
}
Конструктор Student копирует имя и идентификатор студента, переданные ему в качестве аргументов. Виртуальная функция display( ) возвращает строку с описанием объекта Student .
Компиляция файла Student.срр даёт промежуточный файл, который затем может быть быстро объединён с другими файлами в завершённую выполнимую программу.
_________________
261 стр. Глава 22. Разложение классов
«По историческим причинам в большинстве сред С++ этот промежуточный файл имеет расширение.obj или.о ( "объектный файл" ).»
[ Технические подробности ]
Разделение программы - класс GraduateStudent...262
Следующий модуль, представляющийся квазинезависимым, — GraduateStudent . Он может быть помещён в файл Student.срр , однако ряд программ могут работать только со студентами, даже не подозревая о наличии аспирантов.
Класс GraduateStudent сделан мною максимально простым. Вот как выглядит заголовочный файл.
/* GraduateStudent — специальный тип Student */
#ifndef _GRADUATE_STUDENT_
#define _GRADUATE_STUDENT_
#include "student.h"
namespace Schools
{
class GraduateStudent : public Student
{
public :
/* Тривиальный конструктор */
GraduateStudent( char* pszName , int nID )
: Student( pszName , nID ){ }
/* Демонстрация виртуальной функции */
virtual char* display( ) ;
} ;
}
#endif
Обратите внимание, что файл GraduateStudent.h включает файл Student.h . Это связано с тем, что класс GraduateStudent зависит от определения класса Student . Файл с исходным кодом содержит реализацию метода display( ) .
/* GraduateStudent — специальный тип Student */
#include
#include
#include
#include
#include "graduateStudent.h"
namespace Schools
{
char* GraduateStudent::display( )
{
/* Описание студента */
char* pFirst = Student::display( ) ;
/* Добавляем этот текст */
char* pSecond = "-G" ;
/* Выделяем память для новой строки и создаём её */
char* pName = new char[ strlen( pFirst ) +
strlen( pSecond ) + 1 ] ;
strcpy( pName , pFirst ) ;
strcat( pName , pSecond ) ;
/* Освобождаем память, которую вернул вызов Student::display( ) */
delete pFirst ;
return pName ;
}
}
_________________
262 стр. Часть 4. Наследование
Функция display( ) из класса GraduateStudent добавляет "-G" к строке, возвращаемой функцией display( ) из класса Student . Она начинает свою работу с того, что выделяет память из кучи для новой строки.
«Никогда не надо полагаться на то, что в исходном буфере имеется достаточно места для дополнительных символов, дописываемых в конец строки.»
[ Атас! ]
Программа копирует в новый буфер полученную от функции display( ) из класса Student строку, добавляет к ней "-G" и освобождает память, которую занимала исходная строка.
«Забыв освободить память, выделенную в куче, вы получите эффект, именуемый утечкой памяти. Программа с утечкой памяти поначалу работает вполне корректно, но со временем всё большее и большее количество памяти оказывается потерянным, что может привести к неработоспособности программы из-за отсутствия памяти. Обычно утечки памяти очень трудно обнаружить.»
[ Атас! ]
Реализация приложения...263
Два класса — Student и GraduateStudent — разнесены по отдельным исходным файлам и размещены в пространстве имён Schools . Я написал простенькую программу, использующую оба описанных класса.
//
/* SeparatedMain — демонстрационное приложение, */
/* разделённое на части */
//
#include
#include
#include
#include
#include "graduateStudent.h"
#include "student.h"
using namespace std ;
/* using namespace Schools ; */
using Schools::GraduateStudent ;
int main( int nArgc , char* pszArgs[ ] )
{
Schools::Student s( "Sophie Moore" , 1234 ) ;
Читать дальшеИнтервал:
Закладка: