Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП Лекции PDF / ООП 02 Лек Классы.pdf
Скачиваний:
67
Добавлен:
15.02.2015
Размер:
325.31 Кб
Скачать

Лекция 2

Классы

1

 

Л Е К Ц И Я

2

КЛАССЫ________________________________________________________________________________ 1

Синтаксис объявления класса ____________________________________________________________ 1 Пример объявление класса ______________________________________________________________ 1 Определение функции-члена класса_______________________________________________________ 2 Создание объекта класса ________________________________________________________________ 2 Использование указателя на объект _______________________________________________________ 2 Динамические объекты __________________________________________________________________ 3 Использование операции разрешения видимости ____________________________________________ 3 Ограничения на данные-члены класса _____________________________________________________ 3 Неполное объявление класса_____________________________________________________________ 3 Спецификаторы доступа _________________________________________________________________ 4 Создание класса в среде разработки MS Visual Studio 6.0 _____________________________________ 4

КЛАССЫ

Синтаксис объявления класса

Понятие класса является наиболее важным в языке C++. Синтаксис объявления класса похож на синтаксис описания структуры. Вот его основная форма:

class <имя_класса>

{

<закрытые_элементы_класса> protected:

<защищённые_элементы_класса> public:

<открытые_элементы_класса> }<список_объектов> ;

где

 

<имя_класса>

необязательно, хотя его обычно указывают. <имя_класса> становится но-

 

вым именем типа данных, которое используется для объявления объектов

<список_объектов>

этого класса;

необязательный, объявить объекты класса можно позже, по мере необхо-

 

димости.

Функции и переменные, объявленные внутри объявления класса, становятся членами этого класса: переменные, объявленные внутри объявления класса, называются данными-членами этого класса; функции, объявленные внутри объявления класса, называются функциями-членами этого класса.

По умолчанию, все функции и переменные, объявленные в классе, становятся закрытыми для этого класса. Это означает, что они доступны только для других членов этого класса. Для объявления открытых членов класса используется ключевое слово public, за которым следует двоеточие. Все функции и переменные, объявленные после слова public, доступны и для других членов класса, и для любой другой части программы, в которой содержится класс.

Пример объявление класса

Вот пример объявления класса, который содержит закрытое данное-член класса x и две открытые функции-члены класса для изменения и получения данного-члена класса x.

class AnyClass

{

int x;

// закрытое данное-член класса

public:

// открытые члены класса

int GetX ( ) ;

// функция возвращает значение данного-члена класса x

void SetX ( int X ) ;

// функция изменяет значение данного-члена класса x

}

 

Обратите внимание на объявление функции-члена void SetX( int X ). Параметр функции X отличен от данного-члена класса x, поскольку компилятор C++ различает прописные и строчные буквы. Использование в списке параметров идентификаторов, совпадающих с данными-членами, усложнит код вашей программы и затруднит её чтение.

Выжол Ю.А.

Объектно-ориентированное программирование

Лекция 2

Классы

2

Вприведённом выше примере данные являются закрытыми, и манипулировать с ними можно только

спомощью членов класса. Этот приём позволяет защитить данные от некорректных действий со стороны пользователя. Программист, использующий класс, может в этом случае и не разбираться в структуре данных класса.

Определение функции-члена класса

Хотя функции GetX( ) и SetX( ) и объявлены в классе AnyClass, они еще не определены. Для определения функции-члена нужно связать имя класса, частью которого является функция-член, с именем функции. Это достигается путем написания имени функции вслед за именем класса с двумя двоеточиями. Операцию, записываемую в виде двух двоеточий, называют операцией расширения области видимости. Для задания функции-члена используется следующая общая форма:

<тип_функции> <имя_класса> :: <имя_функции> ( <список_параметров> )

{

<тело_функции>

}

Ниже приведены примеры определения функций-членов GetX( ) и SetX( ):

int AnyClass :: GetX ( )

{

return x ;

}

void AnyClass :: SetX ( int X )

{

x = X ;

}

Если тело функции-члена класса невелико по объёму, как в приведённом выше примере, то описание функции удобно привести в объявлении класса в соответствии со следующим синтаксисом:

<тип_функции> <имя_функции> ( <список_параметров> ) { <тело_функции> }

В этом случае чтение и редактирование класса упростится, и он будет иметь следующий вид:

class AnyClass

{

int x;

 

// закрытое данное-член класса

public:

 

// открытые члены класса

int GetX ( )

{ return x ; }

// функция возвращает значение данного-члена класса x

void SetX ( int X )

{ x = X ; }

// функция изменяет значение данного-члена класса x

}

 

 

Создание объекта класса

Объявление класса AnyClass не приводит к созданию объектов типа AnyClass. Чтобы создать объект соответствующего класса, нужно просто использовать имя класса как спецификатор типа данных. Например:

void main ( )

{

AnyClass obA , оbB ;

// создание двух объектов

obA . SetX ( 1 ) ;

// изменение значение данного-члена x в объекте obA

obB . SetX ( 3 ) ;

// изменение значение данного-члена x в объекте obB

}

 

После того, как объект класса создан, можно обращаться к открытым членам класса, используя операцию "точка", так же как к полям структуры.

Эти операторы устанавливают значения переменной а в объектах obA и оbB . Каждый объект содержит собственную копию всех данных, объявленных в классе. Это значит, что значение переменной x в o- bA отлично от значения этой переменной в оbB.

Использование указателя на объект

Доступ к элементам данных класса можно получить и с помощью указателя на объект этого класса. Следующий пример это иллюстрирует.

void main( )

{

Выжол Ю.А.

Объектно-ориентированное программирование

Лекция 2

Классы

3

AnyClass A ;

// создание объекта

 

AnyClass * pA = &A;

// создание указателя на объект класса AnyClass

 

pA -> SetX ( 1 ) ;

// и его инициализация адресом переменной A

 

// изменение значение данного-члена x в объекте A

 

}

 

 

Оператор выбора члена "точка" работает в точности так же, как оператор "->", за исключением того, что имени объекта предшествует неявно сгенерированный компилятором оператор адреса "&". Таким образом, инструкцию

ObjName . FuncName ( ) ;

компилятор трактует, как

( &ObjName ) -> FuncName ( ) ;

Динамические объекты

Доступ к элементам данных класса можно получить и с помощью указателя на объект этого класса. Следующий пример это иллюстрирует.

void main( )

{

AnyClass * pA = new AnyClass ;

pA -> SetX ( 1 ) ;

// изменение значение данного-члена x в объекте, на который указывает pA

delete pA ;

// удаление объекта из кучи

}

В первой строке тела функции выполняются следующие действия: объявляется указатель pA на объект класса AnyClass, выделяется память для объекта класса AnyClass куче, вызывается конструктор и создаётся объект класса AnyClass, указатель инициализируется адресом выделенной памяти.

Использование операции разрешения видимости

Имена элементов класса могут также использоваться с именем класса, за которым следует операция разрешения видимости (двойное двоеточие), то есть вызов элемента имеет вид:

<имя_класса> :: <имя_члена>

Подробнее эту форму вызова элементов класса мы рассмотрим позднее.

Ограничения на данные-члены класса

Язык C++ накладывает определенные ограничения на данные-члены класса: данные-члены не могут определяться с модификаторами auto, extern или register;

данным-членом класса не может быть объект этого же класса (однако данным-членом может быть указатель или ссылка на объект этого класса, или сам объект другого класса).

Имена всех элементов класса (данных и функций) имеют своей областью действия этот класс. Это означает, что функции-члены могут обращаться к любому элементу класса просто по имени.

Неполное объявление класса

Класс должен быть объявлен до использования его членов. Однако иногда в классе должен быть объявлен указатель или ссылка на объект другого класса еще до того, как он определен. В этом случае приходится прибегать к неполному объявлению класса, которое имеет вид:

class <имя_класса> ;

Рассмотрим пример.

 

class PrevDecl ;

// неполное объявление класса PrevDecl

class AnyClass

 

{

 

int x;

 

PrevDecl* obPtr;

 

public:

AnyClass ( int X ) { x = X ; } // конструктор класса AnyClass

};

Выжол Ю.А. Объектно-ориентированное программирование

Лекция 2

Классы

4

class PrevDecl

// полное объявление класса PrevDecl

 

{

 

 

int y;

 

 

public :

 

 

PrevDecl ( ) ;

// конструктор класса PrevDecl

 

} ;

 

 

Нельзя создать объект не полностью определенного класса. Попытка создания такого класса приводит к ошибке компиляции.

Заметим, что определение класса напоминает определение структуры, за исключением того, что определение класса:

обычно содержит один или несколько спецификаторов доступа, задаваемых с помощью ключевых слов public, protected или private;

вместо ключевого слова struct могут применяться class или union; обычно включает в себя наряду с элементами данных функции-члены;

обычно содержит некоторые специальные функции-члены, такие, как конструктор и деструктор.

Спецификаторы доступа

Спецификатор доступа применяется ко всем элементам класса, следующим за ним, пока не встретится другой спецификатор доступа или не закончится определение класса. Ниже описываются спецификатора доступа:

private

данные-члены и функции-члены доступны только для функций-членов этого класса.

protected

данные-члены и функции-члены доступны для функций-членов данного класса и клас-

public

сов, производных от него.

данные-члены и функции-члены класса доступны для функций-членов этого класса и

 

других функций программы, в которой имеется представитель класса.

Создание класса в среде разработки MS Visual Studio 6.0

Класс, который мы создали можно разместить в том же файле, что и основная программа, которая содержит функцию main ( ) и использует этот класс. Но такое решение целесообразно только в том случае, если ваша программа невелика по объёму. Хорошим стилем программирования считается размещение каждого класса в отдельном файле и дальнейшее подключение его к основной программе с помощью директивы #include.

Более того, синтаксис языка C++ предполагает размещение класса в двух файлах – в заголовочном файле c расширением *.h и в связанном с ним исполняемым файлом с расширением *.cpp. Оба файла должны иметь одно и то же имя. Как правило, это имя совпадает с именем класса. В заголовочном файле размещают объявление класса, а в исполняемом файле – описание функций-членов класса. Кроме того, необходимо позаботится о связи файлов, и предотвратить возможность повторного включения класса в код программы при компиляции.

Все эти действия автоматически выполняет соответствующий мастер в среде разработки MS Visual Studio 6.0. Для создания класса:

в меню Insert выберите команду New Class … ;

в диалоговом окне New Class в поле Name введите имя класса, например, Newton; нажмите кнопку OK.

При этом в вашем проекте появятся два новых файла: Newton.cpp и Newton.h

Выжол Ю.А.

Объектно-ориентированное программирование

Лекция 2

Классы

5

Мастер создания классов имеет особенность. Как правило, имена классов начинаются с префикса C, а в именах файлов класса этот префикса отсутствует. Например, если вы хотите создать класс CString, то мастер создаст класс с указанным именем и разместит класс в файлах String.h и String.cpp. Если вас это правило не устраивает то:

вдиалоговом окне New Class нажмите кнопку Change …

вдиалоговом окне Change Files введите новые имена файлов. Файл Newton.h содержит объявление класса и имеет следующий вид:

#if !defined(AFX_NEWTON_H__D3983B9F_3F43_43DF_95F1_AAD68FB9BC00__INCLUDED_) #define AFX_NEWTON_H__D3983B9F_3F43_43DF_95F1_AAD68FB9BC00__INCLUDED_

#if _MSC_VER > 1000 #pragma once

#endif // _MSC_VER > 1000 class Nuwton

{

public: Newton ( ) ;

virtual ~Newton ( ) ;

} ;

#endif // !defined(AFX_NEWTON_H__D3983B9F_3F43_43DF_95F1_AAD68FB9BC00__INCLUDED_)

Мастер создания классов сгенерировал уникальный идентификатор файла:

AFX_NEWTON_H__D3983B9F_3F43_43DF_95F1_AAD68FB9BC00__INCLUDED_.

Идентификатор файла содержит имя класса и случайные символы. Поэтому идентификатор файла каждый раз будет другим.

В первых строках файла директивы препроцессора осуществляют проверку существования идентификатора файла в программе. Если идентификатор файла в программе существует, то это означает, что класс в программе уже объявлен, и повторно объявлять его не нужно.

Удалять из файла строки с директивами препроцессора не следует !!!

Созданный мастером класс содержит объявления конструктора и деструктора.

Файл Newton.cpp содержит описание конструктора и деструктора и имеет следующий вид:

#include "Newton.h"

Newton :: Newton ( )

{

}

Newton :: ~ Newton ( )

{

}

Теперь мы можем дополнять класс объявлениями новых данных-членов и функций-членов в файле Newton.h. Реализация функций-членов мы будем помещать в файл Newton.cpp. Для того, чтобы использовать класс, его нужно подключить к файлу, в котором мы хотим создать объекты типа Newton с помощью директивы:

#include "Newton.h"

Имя файла заключено в двойные кавычки. Это означает, что компилятор должен искать файл в папке проекта.

Выжол Ю.А.

Объектно-ориентированное программирование