- Lektsia - бесплатные рефераты, доклады, курсовые работы, контрольные и дипломы для студентов - https://lektsia.info -

Setab(0); // для уже известного объекта.



}

Int main()

{

 myclass ob;

 ob.setab(5); // Устанавливаем члены данных ob.a и ob.b.

 cout << "Объект ob после вызова функции setab(5): ";

 cout << ob.geta() << ' ';

 cout << ob.b; // К члену b можно получить прямой доступ, поскольку он является public-членом.

 cout << '';

 ob.b = 20; // Член b можно установить напрямую, поскольку он является public-членом.

 cout << "Объект ob после установки члена ob.b=20: ";

 cout << ob.geta() <<' ';

 cout << ob.b;

 cout << '';

 ob.reset();

 cout << "Объект ob после вызова функции ob.reset(): ";

 cout << ob.geta() << ' ';

 cout << ob.b;

 cout << '';

 return 0;

}

При выполнении этой программы получаем следующие результаты.

Объект ob после вызова функции setab(5): 5 25

Объект ob после установки члена ob.b=20: 5 20

Объект ob после вызова функции ob.reset(): 0 0

Теперь рассмотрим, как осуществляется доступ к членам класса myclass. Прежде всего обратите внимание на то, что для присвоения значений переменным а и b в функции setab() используются следующие строки кода.

а = i; // прямое обращение к переменной а

b = i*i; // прямое обращение к переменной b

Поскольку функция setab() является членом класса, она может обращаться к членам данных а и b того же класса непосредственно, без явного указания имени объекта (и не используя оператор "точка"). Как упоминалось выше, функция-член всегда вызывается для определенного объекта (а коль вызов состоялся, объект, стало быть, известен). Таким образом, в теле функции-члена нет необходимости указывать объект вторично. Следовательно, ссылки на переменные а и b будут применяться к копиям этих переменных, относящимся к вызывающему объекту.

Теперь обратите внимание на то, что переменная b — открытый (public) член класса myclass. Это означает, что к b можно получить доступ из кода, определенного вне тела класса myclass. Следующая строка кода из функции main(), при выполнении которой переменной b присваивается число 20, демонстрирует реализацию такого прямого доступа.

ob.b = 20; // К члену b можно получить прямой доступ.

// поскольку он является public-членом.

Поскольку эта инструкция не принадлежит телу класса myclass, то к переменной b возможен доступ только с использованием конкретного объекта (в данном случае объекта ob) и оператора "точка".

Теперь обратите внимание на то, как вызывается функция-член reset() из функции main().

ob.reset();

Поскольку функция reset() является открытым членом класса, ее также можно вызвать из кода, определенного вне тела класса myclass, и посредством конкретного объекта (в данном случае объекта ob).

Наконец, рассмотрим код функции reset(). Тот факт, что она является функцией-членом, позволяет ей непосредственно обращаться к другим членам того же класса, не используя оператор "точка" или конкретный объект. В данном случае она вызывает функцию-член setab(). И снова-таки, поскольку объект уже известен (он используется для вызова функции reset()), нет никакой необходимости указывать его еще раз.

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

На заметку. Не стоит волноваться, если вы еще не почувствовали в себе уверенность в вопросах получения доступа к членам класса. Небольшое беспокойство при освоении этой темы — обычное явление для начинающих программистов. Смело продолжайте читать книгу, рассматривая как можно больше примеров, и тема доступа к членам класса вскоре станет такой же простой, как таблица умножения!

Конструкторы и деструкторы

Конструктор — это функция, которая вызывается при создании объекта.

Как правило, некоторую часть объекта, прежде чем его можно будет использовать, необходимо инициализировать. Например, рассмотрим класс queue (он представлен выше в этой главе). Прежде чем класс queue можно будет использовать, переменным rloc и sloc нужно присвоить нулевые значения. В данном конкретном случае это требование выполнялось с помощью функции init(). Но, поскольку требование инициализации членов класса весьма распространено, в C++ предусмотрена реализация этой возможности при создании объектов класса. Такая автоматическая инициализация выполняется благодаря использованию конструктора.

Конструктор — это специальная функция, которая является членом класса и имя которой совпадает с именем класса. Вот, например, как стал выглядеть класс queue после переделки, связанной с применением конструктора для инициализации его членов.

// Определение класса queue.

class queue {

  int q[100];

  int sloc, rloc;

 public:

  queue(); // конструктор

  void qput(int i);

  int qget();

};

Обратите внимание на то, что в объявлении конструктора queue() отсутствует тип возвращаемого значения. В C++ конструкторы не возвращают значений и, следовательно, нет смысла в указании их типа. (При этом нельзя указывать даже тип void.)

Теперь приведем код функции queue().

// Определение конструктора.

Queue::queue()

{

 sloc = rloc = 0;

 cout << "Очередь инициализирована.";

}

В данном случае при выполнении конструктора выводится сообщение Очередь инициализирована., которое служит исключительно иллюстративным целям. На практике же в большинстве случаев конструкторы не выводят никаких сообщений.

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

Деструктор — это функция, которая вызывается при разрушении объекта.

Дополнением к конструктору служит деструктор. Во многих случаях при разрушении объекту необходимо выполнить некоторое действие или даже некоторую последовательность действий. Локальные объекты создаются при входе в блок, в котором они определены, и разрушаются при выходе из него. Глобальные объекты разрушаются при завершении программы. Существует множество факторов, обуславливающих необходимость деструктора. Например, объект должен освободить ранее выделенную для него память. В C++ именно деструктору поручается обработка процесса дезактивизации объекта. Имя деструктора совпадает с именем конструктора, но предваряется символом "~" Подобно конструкторам деструкторы не возвращают значений, а следовательно, в их объявлениях отсутствует тип возвращаемого значения.

Рассмотрим уже знакомый нам класс queue, но теперь он содержит конструктор и деструктор. (Справедливости ради отметим, что классу queue деструктор, по сути, не нужен, а его наличие здесь можно оправдать лишь иллюстративными целями.)

// Определение класса queue.

class queue {

  int q[100];

  int sloc, rloc;

 public:

  queue(); // конструктор

  ~queue(); // деструктор

  void qput(int i);

  int qget();

};

// Определение конструктора.

Queue::queue()

{

 sloc = rloc = 0;

 cout << "Очередь инициализирована.";

}

// Определение деструктора.

queue::~queue()

{

 cout << "Очередь разрушена.";

}

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

// Демонстрация использования конструктора и деструктора.

#include <iostream>

using namespace std;

// Определение класса queue.

class queue {

  int q[100];

  int sloc, rloc;

 public:

  queue(); // конструктор

  ~queue(); // деструктор

  void qput(int i);

  int qget();

};

// Определение конструктора.

Queue::queue()

{

 sloc = rloc = 0;

 cout << "Очередь инициализирована.";

}

// Определение деструктора.

queue::~queue()

{

 cout << "Очередь разрушена.";

}

// Занесение в очередь целочисленного значения.

Void queue::qput(int i)

{

 if(sloc==100) {

  cout << "Очередь заполнена.";

  return;

 }

 sloc++;

 q[sloc] = i;

}

// Извлечение из очереди целочисленного значения.

Int queue::qget()

{

 if(rloc == sloc) {

  cout << "Очередь пуста.";

  return 0;

 }

 rloc++;

 return q[rloc];

}

Int main()

{

 queue a, b; // Создание двух объектов класса queue.

 a.qput(10);

 b.qput(19);

 a.qput(20);

 b.qput(1);

 cout << a.qget() << " ";

 cout << a.qget() << "";

 cout << b.qget() << " ";

 cout << b.qget() << "";

 return 0;

}