yandex rtb 1
ГоловнаЗворотній зв'язок
yande share

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

Лекция 4.

Классы и объекты в языке C++. Создание, уничтожение объектов и классы памяти.

 

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

Рассмотрим, как это делается в языке C++.

Класс в языке C++ - это агрегатный тип, который объединяет поля и методы в единую языковую конструкцию. Класс объявляется с использованием ключевого слова class. В простейшем виде класс описывается следующим образом:

class classname {

type variable1;

type variable2;

access_specifier:

type methodname1(parameter_list) {

//тело метода

}

type methodname2(parameter_list) {

//тело метода

}

}

 

Приведем пример:

class pair

{

int first;

char second;

public:

bool compare(pair c)

{

if (first==c.first && second==c.second)

return true;

else return false;

}

void setfirst(int f)

{

first=f;

}

void setsecond(char s)

{

second=s;

}

};

 

Здесь описан некоторый класс с именем pair, который имеет два поля – first и second и несколько методов. При этом мы указываем, что все методы имеют доступ public, т.е. мы можем обращаться к нашим методам вне класса. Для полей не указан никакой спецификатор метода доступа. Дело в том, что по умолчанию, если спецификатор метода доступа не указан, предполагается доступ private. Поэтому указанная выше декларация идентична следующей:

class pair

{

private:

int first;

char second;

public:

};

Описанная выше декларация класса является удобной только в случае очень небольшого класса. Если же методов достаточно много, а сами они сложны и объемны, имеет смысл отделить описание класса от реализации. Это тем более важно, так как язык C++ допускает раздельную компиляцию модулей. Поэтому, например, описание класса может быть выделено в отдельный, заголовочный модуль, а реализация методов будет производиться в другом, основном модуле. Поэтому наш класс может быть записан следующим образом:

class pair

{

private:

int first;

char second;

public:

bool compare(pair c);

void setfirst(int f);

void setsecond(char s);

};

bool pair::compare(pair c)

{

     if (first==c.first && second==c.second)

          return true;

      else return false;

}

void pair::setfirst(int f)

{

first=f;

}

void pair::setsecond(char s)

{

second=s;

}

Таким образом, для указания того, что некоторая функция или переменная являются частью класса, вводится оператор разрешения области видимости. Он имеет вид:

classname::variable

тем самым мы указываем, что функции compare, setfirst, setsecond принадлежат классу pair. Боле того, в одном и том же методе мы можем использовать переменные с одним именем, но принадлежащие разным областям видимости. Например, функцию setfirst можно было бы объявить следующим образом:

void pair::setfirst(int first)

{

pair::first=first;

}

Здесь first – абсолютно разные переменные. Одна является полем класса pair, а вторая – передается в качестве параметра в метод класса.

Описание класса не означает создание объекта. Класс – это только некоторая схема, описание типа данных. Для создания объекта необходимо предпринимать дополнительные усилия, которые зависят от того, каким образом мы хотим создать наш объект и как мы его будем использовать. Для того, чтобы разобраться в методах создания объектов, необходимо разобраться в классах памяти. Заметим, что классы памяти никоим образом не имеют отношения к классам как типам данных.

Объекты могут быть созданы в следующих формах:

-          глобальные объекты. Создаются в начале создаваемой программы и разрушаются при ее завершении.

-          автоматические объекты. Создаются, когда их объявление встречается в выполняемой программе, и разрушаются, когда блок программы, в котором они были объявлены, разрушается или удаляется из памяти.

-          статические объекты. Создаются один раз при запуске программы и разрушаются тоже один раз при завершении выполнения программы.

-          Объекты в динамической памяти. Создаются в процессе выполнения программы оператором new и разрушаются оператором delete.

-          Объекты-компоненты классов. Создаются при построении объекта и разрушаются при разрушении этого объекта.

Рассмотрим на примере, каким образом создаются в программе автоматические и динамические объекты и как осуществляется доступ к методам объектов в том и другом случае.

void main()

{

pair a;

pair *b;

a.setfirst(10);

a.setsecond('q');

b=new pair;

b->setfirst(10);

b->setsecond('q');

if (a.compare(*b))

cout<<"equal";

else

cout<<"different";

a.setfirst(11);

if (b->compare(a))

cout<<"equal";

else

cout<<"different";

delete b;

}

Данный пример демонстрирует два принципиально разных подхода. Объект a создается автоматически в начале программы (в данном случае) и будет уничтожен, когда программа закончит свою работу. В общем случае автоматические объекты создаются в блоке, в котором они объявлены и уничтожаются при выходе из этого блока. Объект b создается динамически тогда, когда будет выполнен оператор new. Уничтожение такого объекта происходит с использованием, когда будет выполнен оператор delete. Заметим, что и при создании и при уничтожении объекта мы используем указатель на объект.

По разному происходит и обращение к методам (и, если такое возможно, к полям) класса. Для автоматических объектов доступ к компонентам класса производится с помощью точечной нотации:

object.method

Именно такой доступ был продемонстрирован ранее при описании метода compare класса pair.

Для динамических объектов доступ производится с помощью указателя:

pointer->method

 

6