Официальный сайт netfuncards 24/7/365

НФПК
Проект реализуется
Национальным фондом подготовки кадров
Вы не зарегистрированы

Авторизация



C++ для начинающих

Фото пользователя Игорь Юрьевич Дяжур
Размещено: Игорь Юрьевич Дяжур - чт, 22/12/2011 - 22:18
Данные об авторе
Автор(ы): 
Дяжур Игорь
Место работы, должность: 

Студент ИТО

МГПИ

Регион: 
Город Москва
Характеристики ресурса
Уровни образования: 
начальное профессиональное образование
Предмет(ы): 
Информатика и ИКТ
Целевая аудитория: 
Учащийся (студент)
Тип ресурса: 
дидактический материал
Краткое описание ресурса: 
<h1 class="title"> Учебник по C++ для начинающих.<strong> </strong>Часть 4. Использовние классов C++.</h1>

Часть 4. Использовние классов C++

Урок 21 Знакомство с классами C++

Класс представляет собой главное инструментальное средство C++ для объектно-ориентированного программирования. Как вы узнаете из данного урока, класс очень похож на структуру, в которой сгруппированы элементы, соответствующие данным о некотором объекте, и оперирующие этими данными функции (называемые методами). Вы узнаете, что объект представляет собой некоторую сущность, например телефон. Класс C++ позволяет вашим программам определять все атрибуты объекта. В случае, когда объектом является телефон, класс может содержать такие элементы данных, как номер и тип телефона (кнопочный или дисковый) и функции, работающие с телефоном, например dial, answer, и hang_up. Группируя данные об объекте и кодируя их в одной переменной, вы упрощаете процесс программирования и увеличиваете возможность повторного использования своего кода. Этот урок знакомит вас с классами C++ . К концу урока вы освоите следующие основные концепции:

6.      Для определения класса программа должна указать имя класса, элементы данных класса и функции класса (методы).

7.      Определение класса обеспечивает шаблон, с помощью которого ваши программы могут создать объекты типа этого класса, подобно тому, как программы создают переменные типа int, char и т. д.

8.      Программа присваивает значения элементам данных класса, используя оператор точку.

9.      Программа вызывает функцию-элемент класса, используя оператор точку.

ПРЕДСТАВЛЕНИЕ ОБ ОБЪЕКТАХ И ОБЪЕКТНО-ОРИЕНТИРОВАННОМ ПРОГРАММИРОВАНИИ

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

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

class class_name

{
   int data_member; // Элементданных
   void show_member(int); // Функция-элемент
};

После определения класса вы можете объявлять переменные типа этого класса (называемые объектами), как показано ниже:

class_name object_one, object_two, object_three;

Следующее определение создает класс employee, который содержит определения данных и метода:

class employee

{
   public:
   char name[64] ;
   long employee_id;
   float salary;
   void show_employee(void)

{
      cout << "Имя: " << name << endl;
      cout << "Номерслужащего: " << employee_id << endl;
      cout << "Оклад: " << salary << endl;
   };
};

В данном случае класс содержит три переменные и одну функцию-элемент. Обратите внимание на использование метки public внутри определения класса. Как вы узнаете из урока 22, элементы класса могут быть частными (private) или общими {public), от чего зависит, как ваши программы обращаются к элементам класса. В данном случае все элементы являются общими, это означает, что программа может обращаться к любому элементу, используя оператор точку. После определения класса внутри вашей программы вы можете объявить объекты (переменные) типа этого класса, как показано ниже:

————————————————————— Имя класса

employee worker, boss, secretary ; //--------->Переменные класса (объекты)

Следующая программа EMPCLASS.CPP создает два объекта employee. Используя оператор точку, программа присваивает значения элементам данных Затем программа использует элемент show_employee для вывода информации о служащем:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   char name [64];
   long employee_id;
   float salary;
   void show_employee(void)

{
      cout << "Имя: " << name << endl;
      cout << "Номерслужащего: " << employee_id << endl;
      cout << "Оклад: " << salary << endl;
   };
};

void main(void)

{
   employee worker, boss;
   strcpy(worker.name, "John Doe");
   worker.employee_id = 12345;
   worker.salary = 25000;
   strcpy(boss.name, "Happy Jamsa");
   boss.employee_id = 101;
   boss.salary = 101101.00;
   worker.show_employee();
   boss.show_employee();
}

Как видите, программа объявляет два объекта типа employee — worker и boss, а. затем использует оператор точку для присваивания значений элементам и вызова функции show_employee.

Представление об объектах

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

ОПРЕДЕЛЕНИЕ МЕТОДОВ КЛАССА ВНЕ КЛАССА

В предыдущем классе employee функция была определена внутри самого класса (встроенная (inline) функция). При увеличении функций определение встроенных функций внутри класса может внести беспорядок в описание класса. В качестве альтернативы вы можете поместить прототип функции внутри класса, а затем определить функцию вне класса. Ваше определение класса с прототипом становится следующим:

class employee

{
public:
   char name[64];
   long employee_id;
   float salary;
   void show_employee(void); |————————> Прототип функции
};

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

void employee:: show_employee (void) //-------------->Имя класса

{
   сout << "Имя: " << name << endl; Имя элемента cout << "Номер служащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
};

Как видите, приведенный код предваряется определением функции с именем класса (employee) и оператором глобального разрешения (::). Следующая программа CLASSFUN.CPP помещает определение функции show_employee вне класса, используя оператор глобального разрешения для указания имени класса:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   char name [64];
   long employee_id;
   float salary;
   void show_employee(void);
};

void employee::show_employee(void)
{
   cout << "Имя: " << name << endl;
   cout << "Номерслужащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
};

void main(void)

{
   employee worker, boss;
   strcpy(worker.name, "John Doe");
   worker.employee_id = 12345;
   worker.salary = 25000;
   strcpy(boss.name, "Happy Jamsa");
   boss.employee_id = 101;
   boss.salary = 101101.00;
   worker.show_employee();
   boss.show_employee();
}

Методы класса

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

Для определения функции вне определения класса ваша программа должна предварять определение функции именем класса и оператором глобального разрешения, как показано ниже:

return_type class_name::function_name(parameters)
{ //
Операторы}

ВТОРОЙ ПРИМЕР

Следующая программа PEDIGREE.CPP создает класс dog, который содержит несколько полей данных и функцию show_breed. Программа определяет функцию класса вне определения самого класса. Затем программа создает два объекта типа dog и выводит информацию о каждой собаке:

#include <iostream.h>

#include <string.h>

class dogs

{
public:
   char breed[64];
   int average_weight;
   int average_height;
   void show_dog(void) ;
};

void dogs::show_breed(void)

{
   cout << "Порода: " << breed << endl;
   cout << "Среднийвес: " << average_weight << endl;
   cout << "Средняявысота: " << average_height << endl;
}

void main(void)

{
   dogs happy, matt;
   strcpy(happy.breed, "Долматин") ;
   happy.average_weight = 58;
   happy.average_height = 24;
   strcpy(matt.breed, "Колли");
   matt.average_weight =22;
   matt.average_height = 15;
   happy.show_breed() ;
   matt.show_breed();
}

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Программы на C++ широко используют классы. Говоря кратко, классы позволяют вашим программам группировать для определенного объекта его данные и методы (функции), которые оперируют этими данными, в одной переменной. Как видите, классы очень похожи на структуры, которые вы рассматривали в уроке 18. Классы C++ являются основой объектно-ориентированного программирования. Следующие уроки расширяют возможности предоставляемые классами. Упоминавшаяся в этом уроке метка public, по являющаяся в определении класса, делает элементы класса доступными для всей программы. Из урока 22 вы больше узнаете о частных и общих элементах класса. До изучения урока 22 убедитесь, что освоили следующие основные концепции:

9.       

1.      В известном смысле объект представляет собой сущность, с которой ваши программы выполняют разные операции.

2.      Программы на C++ представляют объекты посредством классов.

3.      Класс, подобно структуре, содержит элементы. Элементы класса могут хранить информацию (данные) или быть функциями (методами), которые оперируют этими данными.

4.      Каждый класс имеет уникальное имя.

5.      После определения класса вы можете объявлять объекты этого класса, используя имя класса в качестве типа.

6.      Для обращения к элементам класса (как к данным, так и к функциям) ваши программы используют оператор точку.

7.      Программы могут определять функцию класса внутри или вне определения класса. Если вы определяете функцию вне определения класса, вам следует указать имя класса и использовать оператор глобального разрешения, например class:: function.

Урок 22. Частные и общие данные

В уроке 21 вы создали свои первые классы в C++. При этом вы включали метку public в определение класса, чтобы обеспечить программе доступ к каждому элементу класса. Из данного урока вы узнаете, как атрибуты public и private управляют доступом к элементам класса со стороны программы. Вы узнаете, что ваши программы могут обратиться к общим (public) элементам из любой функции. С другой стороны, ваша программа может обращаться к частным (private) элементам только в функциях данного класса. Этот урок подробно исследует частные и общие элементы. К концу данного урока вы освоите следующие основные концепции:

8.      Чтобы управлять тем, как ваши программы обращаются к элементам класса, C++ позволяет вам определять элементы как частные или общие.

9.      Частные элементы дают возможность классу скрыть информацию, которую программе не требуется знать.

10.  Класс, использующий частные элементы, обеспечивает интерфейсные функции, которые обращаются к частным элементам класса.

Как уже вкратце обсуждалось в уроке 21, вы должны поместить в определение класса столько информации об объекте, сколько считаете необходимым. При этом объекты становятся самообеспеченными, что может повысить возможность их повторного использования несколькими программами.

СОКРЫТИЕ ИНФОРМАЦИИ

Как вы уже знаете, класс содержит данные и методы (функции). Для использования класса программы просто должны знать информацию, которую хранит класс (его элементы данных) и методы, которые манипулируют данными (функции). Вашим программам не требуется знать, как работают методы. Более того, программы должны знать только, какую задачу выполняют методы. Например, предположим, что у вас есть класс file. В идеале ваши программы должны знать только то, что этот класс обеспечивает методы file.print, который печатает отформатированную копию текущего файла, или file.delete, который удаляет файл. Вашей программе не требуется знать, как эти два метода работают. Другими словами, программа должна рассматривать класс как "черный ящик". Программа знает, какие методы необходимо вызвать и какие параметры им передать, но программа ничего не знает о рельной работе, выполняющейся внутри класса (в "черном ящике").

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

class employee

{
public:
   char name [64];
   long employee_id;
   float salary;
   void show_employee(void);
}

При создании класса вы могли бы иметь элементы, чьи значения используются только внутри класса, но обращаться к которым самой программе нет необходимости. Такие элементы являются частными (private), и их следует скрывать от программы. Если вы не используете метку public, то по умолчанию C++ подразумевает, что все элементы класса являются частными. Ваши программы не могут обращаться к частным элементам класса, используя оператор точку. К частным элементам класса могут обращаться только элементы самого класса. При создании класса вам следует разделить элементы на частные и общие, как показано ниже:

class some_class

{
public:
   int some_variable;
   void initialize_private(int, float); //———> Общиеэлементы
   void show_data(void);
private:
   int key_value; //—————————————> Частныеэлементы
   float key_number;
}

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

some_class object; // Создатьобъект
object.some_variable = 1001;
object.initialize_private(2002, 1.2345);
object.show_data()

Если ваша программа пытается обратиться к частным элементам key_value или key_number, используя точку, компилятор сообщает о синтаксических ошибках.

Как правило, вы будете защищать элементы класса от прямого доступа к ним делая их частными. При этом программы не могут непосредственно присваивать значения таким элементам, используя оператор точку. Вместо того чтобы присвоить значение, программа должна вызвать метод класса. Предотвращая прямой доступ к элементам данных, вы, таким образом, можете гарантировать, что им всегда будут присваиваться допустимые значения. Например, предположим что объект nuclear_reactor вашей программы использует переменную с именем melt_down, которая всегда должна содержать значение в диапазоне от 1 до 5. Если элемент melt_down является общим, программа может непосредственно обратиться к элементу, изменяя его значение произвольным образом:

nuclear_reactor.melt_down = 101

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

int nuke::assign_meltdown(int value)

{
   if ((value > 0) && (value <= 5))

{
      melt_down = value;
      return(0); // Успешноеприсваивание
   } else  return(-1); // Недопустимоезначение
}

Методы класса, которые управляют доступом к элементам данных, представляют собой интерфейсные функции. При создании классов вы будете использовать интерфейсные функции для защиты данных своих классов.

Общие и частные элементы

Классы C++ содержат данные и элементы. Чтобы указать, к каким элементам классов ваши программы могут обращаться напрямую, используя оператор точку, C++ позволяет вам определять элементы класса как общие {public) и частные (private). Таким образом, ваши программы могут непосредственно обращаться к любым общим элементам класса, используя оператор точку. С другой стороны, к частным элементам можно обратиться только через методы класса. Как правило, вы должны защищать большинство элементов данных класса, объявляя их частными. Следовательно, единственным способом, с помошью которого ваши программы могут присвоить значение элементам данных, является использование функций класса, которые способны проверить и скорректировать присваиваемые значения.

ИСПОЛЬЗОВАНИЕ ОБЩИХ И ЧАСТНЫХ ЭЛЕМЕНТОВ КЛАССА

Следующая программа INFOHIDE.CPP иллюстрирует использование общих и частных элементов класса. Программаопределяетобъекттипаemployee какпоказанониже:

class employee

{
public:
   int assign_values(char *, long, float);
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64] ;
   long employee_id;
   float salary;
}

Как видите, класс защищает все свои элементы данных, объявляя их частными. Для доступа к элементам данных программа должна использовать интерфейсные функции. Ниже приведена реализация программы INFOHIDE.CPP:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   int assign_values(char *, long, float);
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
);

int employee::assign_values(char *emp_name, long emp_id, float emp_salary)

{
   strcpy(name, emp_name);
   employee_id = emp_id;
   if (emp_salary < 50000.0)

{
      salary = emp_salary;
      return(0); // Успешно
    }
   else
return(-1); // Недопустимыйоклад}

void employee::show_employee(void)

{
   cout << "Служащий: " << name << endl;
   cout << "Номерслужащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
}

int employee::change_salary(float new_salary)

{
   if (new_salary < 50000.0)

{
      salary = new_salary;
      return(0); // Успешно} else return(-1); // Недопустимыйоклад}

long employee::get_id(void)

{
   return(employee_id) ;
}

void main(void)

{
   employee worker;

if (worker.assign_values("Happy Jamsa", 101, 10101.0) == 0)

{
      cout << "Служащемуназначеныследующиезначения" << endl;}
      worker.show_employee();
      if (worker.change_salary(35000.00) == 0)

{
         cout << "Назначенновыйоклад" << endl;
         worker.show_employee();
      }
   }
   else
   cout << "Указаннедопустимыйоклад" << endl;
}

Выберите время, чтобы исследовать операторы программы более подробно. Несмотря на то что программа достаточно длинна, ее функции на самом деле очень просты. Метод assign_values инициализирует частные данные класса. Метод использует оператор if, чтобы убедиться, что присваивается допустимый оклад. Метод show_employee в данном случае выводит частные элементы данных. Методы change_salary и get_id представляют собой интерфейсные функции, обеспечивающие программе доступ к частным данным. После успешной компиляции и запуска этой программы отредактируйте ее и попытайтесь обратиться напрямую к частным элементам данных, используя оператор точку внутри main. Так как вы не можете напрямую обратиться к частным элементам, компилятор сообщит о синтаксических ошибках.

Что такое интерфейсные функции

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

ИСПОЛЬЗОВАНИЕ ОПЕРАТОРА ГЛОБАЛЬНОГО РАЗРЕШЕНИЯ ДЛЯ ЭЛЕМЕНТОВ КЛАССА

Если вы рассмотрите функции в программе INFOHIDE.CPP, вы обнаружите, что имена параметров функции часто предваряются символами етр_, как показано ниже:

int employee::assign_values(char *emp_name, long emp_id, float emp_salary)

Символы етр_ использовались, чтобы избежать конфликта между именами параметров и именами элементов класса. Если подобный конфликт имен всe же происходит, вы можете разрешить его, предваряя имена элементов класса именем класса и оператором глобального разрешения (::). Следующая функция использует оператор глобального разрешения и имя класса перед именем элементов класса. Исходя из этого, любой читающий эти операторы поймет, какие имена соответствуют классу employee:

int employee::assign_values(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0)

{
      employee::salary = salary;

return(0); // Успешно} else
   return(-1); // Недопустимыйоклад
}

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

Использование оператора глобального разрешения для указания элементов класса

При создании функций-элементов класса возможны ситуации, когда имя локальной переменной, которое вы используете внутри функции, конфликтует с именем элемента класса. По умолчанию имя локальной переменной будет переопределять имя элемента класса. Когда происходит подобный конфликт имен, функция может использовать имя класса и оператор глобального разрешения для доступа к элементам класса, как показано ниже:

class_naine: :member_name = some_value;

ЧАСТНЫЕ ЭЛЕМЕНТЫ КЛАССА НЕ ВСЕГДА ЯВЛЯЮТСЯ ДАННЫМИ

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

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Управляя доступом программы к элементам класса, вы снижаете возможность ошибок, которые происходят в результате злоупотребления этими элементами. Чтобы управлять доступом к элементам класса, можно использовать частные элементы. Большинство определений классов C++, которые вы встретите, будут использовать сочетание частных и общих элементов. Одна из наиболее широко используемых операций, которую ваши программы выполняют при создании объекта, представляет собой инициализацию элементов данных объекта. Из урока 23 вы узнаете, что C++ позволяет вам определять специальную функцию, называемую конструктором, которая автоматически вызывается каждый раз при создании объекта. Используя конструктор, ваша программа легко может инициализировать элементы класса. До изучения урока 23 убедитесь, что освоили следующие основные концепции:

10.   

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

2.      Если это не оговорено явно, C++ считает все элементы частными.

3.      Программы присваивают значения и обращаются к частным элементам, используя интерфейсные функции.

4.      При создании программы, манипулирующей элементами класса, вы можете предварять имя каждого элемента именем класса и оператором глобального разрешения (::), например employее::name, для избежания возможных конфликтов имен.

Урок 23. Конструктор и деструктор

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

5.      Конструктор представляет собой метод класса, который облегчает вашим программам инициализацию элементов данных класса.

6.      Конструктор имеет такое же имя, как и класс.

7.      Конструктор не имеет возвращаемого значения.

8.      Каждый раз, когда ваша программа создает переменную класса, C++ вызывает конструктор класса, если конструктор существует.

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

10.  Деструктор имеет такое же имя, как и класс, за исключением того, что вы должны предварять его имя символом тильды (~).

11.  Деструктор не имеет возвращаемого значения.

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

СОЗДАНИЕ ПРОСТОГО КОНСТРУКТОРА

Конструктор представляет собой метод класса, который имеет такое же имя, как и класс. Например, если вы используете класс с именем employee, конструктор также будет иметь имя employee. Подобно этому, для класса с именем dogs конструктор будет иметь имя dogs. Если ваша программа определяет конструктор, C++ будет автоматически вызывать его каждый раз, когда вы создаете объект. Следующая программа CONSTRUC.CPP создает класс с именем employee. Программа также определяет конструктор с именем employee который присваивает начальные значения объекту. Однако конструктор не возвращает никакого значения, несмотря на то, что он не объявляется как void. Вместо этого вы просто не указываете тип возвращаемого значения:

class employee

{
public:
   employee(char *, long, float); //Конструктор
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
};

В вашей программе вы просто определяете конструктор так же, как любой другой метод класса:

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0)
   employee::salary = salary;
   else // Недопустимыйоклад
   employee::salary = 0.0;
}

Как видите, конструктор не возвращает значение вызвавшей функции. Для него также не используется тип void. В данном случае конструктор использует оператор глобального разрешения и имя класса перед именем каждого элемента, как уже обсуждалось в уроке 23. Ниже приведена реализация программы CONSTRUC.CPP:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   employee(char *, long, float);
   void show_employee(void);
   int change_salary(float) ;
   long get_id(void);
private:
   char name [64] ;
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0)
      employee::salary = salary;
   else // Недопустимыйоклад
      employee::salary = 0.0;
}

void employee::show_employee(void)

{
   cout << "Служащий: " << name << endl;
   cout << "Номерслужащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   worker.show_employee();
}

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

employee worker("Happy Jamsa", 101, 10101.0);

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

employee worker("Happy Jamsa", 101, 10101.0);

employee secretary("John Doe", 57, 20000.0);

employee manager("Jane Doe", 1022, 30000.0);

Представление о конструкторе

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

class_name object(valuel, value2, value3)

Конструкторы и параметры по умолчанию

Как вы уже знаете из урока 15, C++ позволяет указывать значения по умолчанию для параметров функции. Если пользователь не указывает каких-либо параметров, функция будет использовать значения по умолчанию. Конструктор не является исключением; ваша программа может указать для него значения по умолчанию так же, как и для любой другой функции. Например, следующий конструктор employee использует по умолчанию значение оклада равным 10000.0, если программа не указывает оклад при создании объекта. Однако программа должна указать имя служащего и его номер:

employee::employee(char *name, long employee_id, float salary = 10000.00)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   if (salary < 50000.0)
      employee::salary = salary;
   else // Недопустимыйоклад
      employee::salary = 0.0;
}

Перегрузка конструкторов

Как вы уже знаете из урока 13, C++ позволяет вашим программам перегружать определения функций, указывая альтернативные функции для других типов параметров. C++ позволяет вам также перегружать конструкторы. Следующая программа CONSOVER.CPP перегружает конструктор employee. Первый конструктор требует, чтобы программа указывала имя служащего, номер служащего и оклад. Второй конструктор запрашивает пользователя ввести требуемый оклад, если программа не указывает его:

employee::employee(char *name, long employee_id)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   do

{
      cout << "Введитеокладдля" << name << " меньше$50000: ";
      cin >> employee::salary;
   }
   while (salary >= 50000.0);
}

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

class employee

{
public:
   employee (char *, long, float);|___ Прототипыперегруженных
   employee(char *, long);          |функций
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
}

Ниже приведена реализация программы CONSOVER.CPP:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   employee(char *, long, float);
   employee(char *, long);
   void show_employee(void);
   int change_salary(float) ;
   long get_id(void);
private:
   char name [64];
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   if (salary < 50000.0) employee::salary = salary;
   else // Недопустимыйоклад
      employee::salary = 0.0;
}

employee::employee(char *name, long employee_id)

{
   strcpy(employee::name, name);
   employee::employee_id = employee_id;
   do

{
    cout << "Введитеокладдля" << name << " меньше$50000: ";
   cin >> employee::salary;
   }
   while (salary >= 50000.0);
}

void employee::show_employee(void)

{
   cout << "Служащий: " << name << endl;
   cout << "Номерслужащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   employee manager("Jane Doe", 102);
   worker.show_employee();
   manager.sbow_employee();
}

Если вы откомпилируете и запустите эту программу, на вашем экране появится запрос ввести оклад для Jane Doe. Когда вы введете оклад, программа отобразит информацию об обоих служащих.

ПРЕДСТАВЛЕНИЕ О ДЕСТРУКТОРЕ

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

Каждая из созданных вами до сих пор программ создавала объекты в самом начале своего выполнения, просто объявляя их. При завершении программ C++ уничтожал объекты. Если вы определяете деструктор внутри своей программы, C++ будет автоматически вызывать деструктор для каждого объекта, когда программа завершается (т.е. когда объекты уничтожаются). Подобно конструктору, деструктор имеет такое же имя, как и класс объекта. Однако в случае деструктора вы предваряете его имя символом тильды (~), как показано ниже:

~class_name (void) //----------->указывает деструктор

{
// Операторы деструктора
}

В отличие от конструктора вы не можете передавать параметры деструктору. Следующая программа DESTRUCT.CPP определяет деструктор для класса employee:

void employee::-employee(void)

{
   cout << "Уничтожение объекта для " << name << endl;
}

В данном случае деструктор просто выводит на ваш экран сообщение о том, что C++ уничтожает объект. Когда программа завершается, C++ автоматически вызывает деструктор для каждого объекта. Ниже приведена реализация программы DESTRUCT.CPP:

#include <iostream.h>

#include <string.h>

class employee

{
public:
   employee(char *, long, float);
   ~employee(void);
   void show_employee(void);
   int change_salary(float);
   long get_id(void);
private:
   char name [64] ;
   long employee_id;
   float salary;
};

employee::employee(char *name, long employee_id, float salary)

{
   strcpy(employee::name, name) ;
   employee::employee_id = employee_id;
   if (salary < 50000.0) employee::salary = salary;
   else // Недопустимыйоклад
   employee::salary в0.0;
}

void employee::-employee(void)

{
   cout << "Уничтожениеобъектадля" << name << endl;
}

void employee::show_employee(void)

{
   cout << "Служащий: " << name << endl;
   cout << "Номерслужащего: " << employee_id << endl;
   cout << "Оклад: " << salary << endl;
}

void main(void)

{
   employee worker("Happy Jamsa", 101, 10101.0);
   worker.show_employee();
}

Если вы откомпилируете и запустите эту программу, на вашем экране появится следующий вывод:

С:\> DESTRUCT <ENTER>

Служащий: Happy Jamsa

Номер служащего: 101

Оклад: 10101

Уничтожение объекта для Happy Jamsa

Как видите, программа автоматически вызывает деструктор, без какого-либо явного вызова функции деструктора. До настоящего момента вашим программам, вероятно, не требовалось использовать деструктор. Однако, когда программы начнут распределять память внутри объектов, вы обнаружите, что деструктор обеспечивает удобный способ освобождения памяти при уничтожении объекта.

Деструкторы

Деструктор представляет собой функцию, которую C++ автоматически запускает, когда он или ваша программа уничтожает объект. Деструктор имеет такое же имя, как и класс объекта; однако вы предваряете имя деструктора символом тильды (~), например ~employee. В своей программе вы определяете деструктор точно так же, как и любой другой метод класса.

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Конструкторы и деструкторы представляют собой специальные функции класса, которые ваша программа автоматически вызывает при создании или уничтожении объекта. Большинство программ используют конструктор для инициализации элементов данных класса. Простые программы, создаваемые сейчас вами, вероятно, не потребуют использования деструктора. Из урока 24 вы узнаете, как перегружать операторы. Другими словами, вы можете переопределить символ плюс таким образом, что он будет добавлять содержимое одной строки к другой. Как вы уже знаете, тип (например, char, float и int) определяет набор значений, которые может хранить переменная, и набор операций, которые ваши программы могут выполнять над этой переменной. Когда вы определяете класс, вы по существу определяете тип. C++ позволяет вам указать, как ведут себя операторы с данным типом. До изучения урока 24 убедитесь, что освоили следующие основные концепции:

11.   

1.      Конструктор представляет собой специальную функцию, которую ваша программа автоматически вызывает каждый раз при создании объекта. Конструктор имеет такое же имя, как и класс объекта.

2.      Конструктор не имеет возвращаемого значения, но вы не указываете ему тип void. Вместо этого вы просто не указываете возвращаемое значение вообще.

3.      Когда ваша программа создает объект, она может передать параметры конструктору во время объявления объекта.

4.      C++ позволяет вам перегружать конструкторы и разрешает использовать значения по умолчанию для параметров.

5.      Деструктор представляет собой специальную функцию, которую ваша программа вызывает автоматически каждый раз при уничтожении объекта. Деструктор имеет такое же имя, как и класс объекта, но его имя предваряется символом тильды (~).

Урок 24. Перегрузка операторов

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

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

6.      Вы перегружаете операторы для улучшения удобочитаемости ваших программ, но перегружать операторы следует только в том случае, если это упрощает понимание вашей программы.

7.      Для перегрузки операторов программы используют ключевое слово C++ operator.

8.      Переопределяя оператор, вы указываете функцию, которую C++ вызывает каждый раз, когда класс использует перегруженный оператор. Эта функция, в свою очередь, выполняет соответствующую операцию.

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

10.  C++ позволяет перегружать большинство операторов, за исключением четырех, перечисленных в таблице 24, которые программы не могут перегружать.

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

ПЕРЕГРУЗКА ОПЕРАТОРОВ ПЛЮС И МИНУС

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

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

class string

{
public:
   string(char *); // Конструктор
   void str_append(char *);
   void chr_minus(char);
   void show_string(void);
private:
   char data[256] ;
};

Как видите, класс определяет функцию str_append, которая добавляет указанные символы к содержимому строки класса. Аналогичным образом функция chr_minus - удаляет каждое вхождение указанного символа из строки класса. Следующая программа STRCLASS.CPP использует класс string для создания двух объектов символьных строк и манипулирования ими.

#include <iostream.h>

#include <string.h>

class string

{
public:
   string(char *); // Конструктор
   void str_append(char *);
   void chr_minus(char);
   void show_string(void);
private:
   char data[256] ;
};

string::string(char *str)

{
   strcpy(data, str);
}

void string::str_append(char *str)

{
   strcat(data, str);
}

void string::chr_minus(char letter)

{
   char temp[256] ;
   int i, j;
   for (i = 0, j = 0; data[i]; i++) // Этубуквунеобходимоудалить?
   if (data[i] != letter) // Еслинет, присвоитьееtemp
   temp[j++] = data[i];
   temp[j] = NULL; // Конецtemp
// Копироватьсодержимоеtemp обратновdata
   strcpy(data, temp);
}

void string::show_string(void)

{
   cout << data << endl;
}

void main(void)

{
   string title( "УчимсяпрограммироватьнаязыкеC++");
   string lesson("Перегрузкаоператоров");
   title.show_string() ;
   title.str_append(" яучусь!");
   itle.show_string();
   lesson.show_string();
   lesson.chr_minus('p') ;
   lesson.show_string();
   }

Как видите, программа использует функцию str_append для добавления символов к строковой переменной title. Программа также использует функцию chr_minus для удаления каждой буквы " р" из символьной строки lesson. В данном случае программа использует вызовы функции для выполнения этих операций. Однако, используя перегрузку операторов, программа может выполнять идентичные операции с помощью операторов плюс (+) и минус (-).

При перегрузке оператора используйте ключевое слово C++ operator вместе с прототипом и определением функции, чтобы сообщить компилятору C++, что класс будет использовать этот метод как оператор. Например, следующее определение класса использует ключевое слово operator, чтобы назначить операторы плюс и минус функциям str_append и chr_minus внутри класса string:

class string

{
public:
   string(char *); // Конструктор
   void operator +(char *);
   void operator -(char); ————— Определениеоператоровклассаvoid show_string(void);
private:
   char data[256];
};

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

void string::operator +(char *str)

{
   strcat(data, str);
}

Как видите, определение этой функции не содержит имени, поскольку здесь определяется перегруженный оператор класса. Для перегрузки оператора плюс программа не изменила обработку, которая осуществляется внутри функции (код этой функции идентичен коду предыдущей функции str_append). Вместо этого программа просто заменила имя функции ключевым словом operators соответствующим оператором. Следующая программа OPOVERLD.CPP иллюстрирует использование перегружаемых операторов плюс и минус:

#include <iostream.h>

#include <string.h>

class string

{
public:
   string(char *); // Конструктор
   void operator +(char *);
   void operator -(char);
   void show_string(void);
private;
   char data[256] ;
};

string::string(char *str)

{
   strcpy(data, str);
}

void string::operator +(char *str)

{
   strcat(data, str);
}

void string::operator -(char letter)

{
   char temp[256] ;
   int i, j;
   for (i = 0, j = 0; data[i]; i++) if (data[il 1= letter) temp[j++] = data[i];
   temp[j] = NULL;
   strcpy(data, temp);
}

void string::show_string(void)

{
   cout << data << endl;
}

void main(void)

{
   string title( "УчимсяпрограммироватьнаC++");
   string lesson("Перегрузкаоператоров");
   title.show_string();
   title + " яучусь!";
   title.show_string() ;
   lesson.show_string();
   lesson - 'P';
   lesson.show_string();
}

Как видите, программа использует перегруженные операторы:

title + " я учусь!"; // Добавить текст " я учусь!"

lesson - 'р'; // Удалить букву 'р'

В данном случае синтаксис оператора законен, но немного непривычен. Обычно вы используете оператор плюс в выражении, которое возвращает результат, например, как в операторе some_str = title + "текст ";. Когда вы определяете оператор, C++ предоставляет вам полную свободу в отношении поведения оператора. Однако, как вы помните, ваша цель при перегрузке операторов состоит в том, чтобы упростить понимание ваших программ. Поэтому следующая программа STR_OVER.CPP немного изменяет предыдущую программу, чтобы позволить ей выполнять операции над переменными типа string, используя синтаксис, который более согласуется со стандартными операторами присваивания:

#include <iostream.h>

#include <string.h>

class string

{
public:
   string(char *); // Конструктор
   char * operator +(char *) ;
   char * operator -(char);
   void show_string(void);
private:
   char data[256] ;
} ;

string::string(char *str)

{
   strcpy(data, str);
}

char * string::operator +(char *str)

{
   return(strcat(data, str));
}

char * string::operator -(char letter)

{
   char temp[256];
   int i, j;
   for (i = 0, j = 0; data[i]; i++) if (data[i] 1= letter) temp[j++] = data[i];
   temp[j] = NULL;
   return(strcpy(data, temp));
}

void string::show_string(void)

{
   cout << data << endl;
}

void main(void)

{
   string title("УчимсяпрограммироватьнаC++");
   string lesson("Перегрузкаоператоров");
   title.show_string();
   title = title + " яучусь";
   title.show_string() ;
   lesson.show_string();
   lesson = lesson - '?';
   lesson.show_string();
}

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

title = title + " учимсяпрограммировать!";

lesson = lesson - 'р';

Второй пример

При создании ваших собственных типов данных с помощью классов наиболее общей операцией будет проверка, являются ли два объекта одинаковыми. Используя перегрузку, ваши программы могут перегрузить операторы равенства (==), неравенства (!=) или другие операторы сравнения. Следующая программа COMP_STR.CPP добавляет новый оператор в класс string, который проверяет, равны ли два объекта string. Используя перегрузку операторов, ваши программы могут проверять, содержат ли строковые объекты одинаковые строки, как показано ниже:

if (some_string == another_string)

Ниже приведена реализация программы COMP_STR.CPP:

#include <iostream.h>

#include <string.h>

class string

{
public:
   string(char *); // конструктор
   char * operator +(char *);
   char * operator -(char);
   int operator ==(string);
   void show_string(void);
private:
   char data[256];
};

string::string(char *str)

{
   strcpy(data, str);
}

char * string::operator +(char *str)

{
   return(strcat(data, str));
}

char * string::operator -(char letter)

{
   char temp[256];
   int i, j;
   for (i = 0, j = 0; data[i]; i++) if (data[i] 1= letter) temp[j++] = data[i];
   temp[j] = NULL;
   return(strcpy(data, temp));
}

int string::operator ==(string str)

{
   int i;
   for (i = 0; data[i] == str.data[i]; i++)
   if ((data[i] == NULL) && (str.data[i] == NULL)) return(1); // Равно
   return (0); //He равно
}

void string::show_string(void)

{
   cout << data << endl;
}

void main(void)

{
   string title( "УчимсяпрограммироватьнаC++");
   string lesson("Перегрузкаоператоров");
   string str( "УчимсяпрограммироватьнаC++");
   if (title == lesson) cout << "title иlesson равны" << endl;
   if (str == lesson) cout << "str иlesson равны" << endl;
   if (title == str) cout << "title иstr равны" << endl;
}

Как видите, перегружая операторы подобным образом, вы упрощаете понимание ваших программ.

ОПЕРАТОРЫ, КОТОРЫЕ Вbl HE МОЖЕТЕ ПЕРЕГРУЗИТЬ

В общем случае ваши программы могут перегрузить почти все операторы С++. В табл. 24 перечислены операторы, которые C++ не позволяет перегружать.

Таблица 24. Операторы C++, которые ваши программы не могут перегрузить.

Оператор

Назначение

Пример

.

Выбор элемента

object.member

.*

Указатель на элемент

object.*member

::

Разрешение области видимости

classname::member

?:

Условный оператор сравнения

с = (а > b) ? а : b;

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Перегрузка операторов — это возможность назначать новый смысл операторам при использовании их с определенным классом. Используя перегрузку операторов, вы можете повысить удобочитаемость ваших программ и облегчить их понимание, выражая операции класса более понятным образом. Из урока 25 вы узнаете, как разделить данные между объектами с помощью элемента static и как использовать методы класса, когда никакие объекты класса не объявляются. До изучения урока 25 убедитесь, что вы освоили следующее:

12.   

1.      Чтобы перегрузить оператор, вы должны определить класс, которому оператор будет назначен.

2.      Когда вы перегружаете оператор, перегрузка действует только для класса, в котором он определяется. Если программа использует оператор с неклассовыми переменными (например, переменными типа int или float), используется стандартное определение оператора.

3.      Чтобы перегрузить оператор класса, используйте ключевое слово C++ operator для определения метода класса, который C++ вызывает каждый раз, когда переменная класса использует оператор.

4.      C++ не позволяет вашим программам перегружать оператор выбора элемента (.), оператор указателя на элемент (.*), оператор разрешения области видимости (::) и условный оператор сравнения (?:).

Урок 25. Статические функции и элементы данных

До настоящего момента каждый создаваемый вами объект имел свой собственный набор элементов данных. В зависимости от назначения вашего приложения могут быть ситуации, когда объекты одного и того же класса должны совместно использовать один или несколько элементов данных. Например, предположим, что вы пишете программу платежей, которая отслеживает рабочее время для 1000 служащих. Для определения налоговой ставки программа должна знать условия, в которых работает каждый служащий. Пусть для этого используется переменная класса state_of_work. Однако, если все служащие работают в одинаковых условиях, ваша программа могла бы совместно использовать этот элемент данных для всех объектов типа employee. Таким образом, ваша программа уменьшает необходимое количество памяти, выбрасывая 999 копий одинаковой информации. Для совместного использования элемента класса вы должны объявить этот элемент как static (статический). Этот урок рассматривает шаги, которые вы должны выполнить для совместного использования элемента класса несколькими объектами. К концу этого урока вы освоите следующие основные концепции:

5.      C++ позволяет иметь объекты одного и того же типа, которые совместно используют один или несколько элементов класса.

6.      Если ваша программа присваивает значение совместно используемому элементу, то все объекты этого класса сразу же получают доступ к этому новому значению.

7.      Для создания совместно используемого элемента данных класса вы должны предварять имя элемента класса ключевым словом static.

8.      После того как программа объявила элемент класса как static, она должна объявить глобальную переменную (вне определения класса), которая соответствует этому совместно используемому элементу класса.

9.      Ваши программы могут использовать ключевое слово static, чтобы сделать метод класса вызываемым в то время, как программа, возможно, еще не объявила каких-либо объектов данного класса.

СОВМЕСТНОЕ ИСПОЛЬЗОВАНИЕ ЭЛЕМЕНТА ДАННЫХ

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

private:
static int shared_value;

После объявления класса вы должны объявить элемент как глобальную переменную вне класса, как показано ниже:

int class_name::shared_value;

Следующая программа SHARE_IT.CPP определяет класс book_series, совместно использующий элемент page_count, который является одинаковым для всех объектов (книг) класса (серии). Если программа изменяет значение этого элемента, изменение сразу же проявляется во всех объектах класса:

#include <iostream.h>

#include <string.h>

class book_series

{
public:
   book_series(char *, char *, float);
   void show_book(void);
   void set_pages(int) ;
private:
   static int page_count;
   char title[64];
   char author[ 64 ];
   float price;
};

int book_series::page__count;

void book_series::set_pages(int pages)

{
   page_count = pages;
}

book_series::book_series(char *title, char *author, float price)

{
   strcpy(book_series::title, title);
   strcpy(book_series::author, author);
   book_series::price = price;
}

void book_series:: show_book (void)

{
   cout << "Заголовок: " << title << endl;
   cout << "Автор: " << author << endl;
   cout << "Цена: " << price << endl;
   cout << "Страницы: " << page_count << endl;
}

void main(void)

{
   book_series programming( "УчимсяпрограммироватьнаC++", "Jamsa", 22.95);
   book_series word( "УчимсяработатьсWord дляWindows", "Wyatt", 19.95);
   word.set_pages(256);
   programming.show_book ();
   word.show_book() ;
   cout << endl << "Изменениеpage_count " << endl;
   programming.set_pages(512);
   programming.show_book();
   word.show_book();
}

Как видите, класс объявляет page_count как static int. Сразу же за определением класса программа объявляет элемент page_count как глобальную переменную. Когда программа изменяет элемент page_count, изменение сразу же проявляется во всех объектах класса book_series.

Совместное использование элементов класса

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

Использование элементов с атрибутами public static, если объекты не существуют

Как вы только что узнали, при объявлении элемента класса как static этот элемент совместно используется всеми объектами данного класса. Однако возможны ситуации, когда программа еще не создала объект, но ей необходимо использовать элемент. Для использования элемента ваша программа должна объявить его как public и static. Например, следующая программа USЕ_MBR.CPP использует элемент page_count из класса book_series, даже если объекты этого класса не существуют:

#include <iostream.h>

#include <string.h>

class book_series

{
public:
   static int page_count;
private:
   char title [64];
   char author[64];
   float price;
};

int book_series::page_count;

void main(void)
{
   book_series::page_count = 256;
   cout << "Текущеезначениеpage_count равно" << book_series::page_count << endl;
}

В данном случае, поскольку класс определяет элемент класса page_count как public, программа может обратиться к этому элементу класса, даже если объекты класса book_series не существуют.

ИСПОЛЬЗОВАНИЕ СТАТИЧЕСКИХ ФУНКЦИЙ-ЭЛЕМЕНТОВ

Предыдущая программа иллюстрировала использование статических элементов данных. Подобным образом C++ позволяет вам определить статические функции-элементы (методы). Если вы создаете статический метод, ваша программа может вызывать такой метод, даже если объекты не были созданы. Например, если класс содержит метод, который может быть использован для данных вне класса, вы могли бы сделать этот метод статическим. Ниже приведен класс menu, который использует esc-последовательность драйвера ANSI для очистки экрана дисплея. Если в вашей системе установлен драйвер ANSI.SYS, вы можете использовать метод clear_screen для очистки экрана. Поскольку этот метод объявлен как статический, программа может использовать его, даже если объекты типа menu не существуют. Следующая программа CLR_SCR.CPP использует метод clear_screen для очистки экрана дисплея:

#include <iostream.h>

class menu

{
public:
   static void clear_screen(void);
   // Здесьдолжныбытьдругиеметоды
private:
   int number_of_menu_options;
};

void menu::clear_screen(void)

{
   cout << '\033' << "[2J";
}

void main(void)

{
   menu::clear_screen();
}

Так как программа объявляет элемент clear_screen как статический, она может использовать эту функцию для очистки экрана, даже если объекты типа menu не существуют. Функция clear_screen использует esc-последовательность ANSI Esc[2J для очистки экрана.

Использование в ваших программах методов класса

По мере создания методов класса возможны ситуации, когда функция, созданная вами для использования классом, может быть полезна для операций вашей программы, которые не включают объекты класса. Например, в классе menu была определена функция clear_screen, которую вы, возможно, захотите использовать в программе. Если ваш класс содержит метод, который вы захотите использовать вне объекта класса, поставьте перед его прототипом ключевое слово static и объявите этот метод как public:

public:
static void clear_screen(void);

Внутри вашей программы для вызова такой функции используйте оператор глобального разрешения, как показано ниже:

menu::clear_screen();

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Из этого урока вы узнали, что, если предварять элемент данных класса ключевым словом static, все объекты данного класса могут совместно использовать этот элемент. Когда элемент данных является общим, ваши программы могут обращаться к его значению, даже если объекты этого класса не существуют. Подобно этому, если ваши программы предваряют общий метод класса ключевым словом static, они могут использовать эту функцию для операций, которые не включают объекты класса. Из урока 26 вы узнаете, как использовать наследование для построения объекта из одного или нескольких уже существующих объектов. Использование наследования для создания новых объектов может сэкономить огромные усилия, затрачиваемые на программирование. До изучения урока 26 убедитесь, что освоили следующие основные концепции:

13.   

1.      Когда вы объявляете элемент класса как static, то такой элемент может совместно использоваться всеми объектами данного класса.

2.      После того как ваша программа объявляет элемент класса как static, она должна вне определения класса объявить глобальную переменную, соответствующую совместно используемому элементу класса.

3.      Если вы объявляете элемент как public и static, ваша программа может использовать такой элемент, даже если объекты данного класса не существуют. Для обращения к этому элементу ваша программа должна использовать оператор глобального разрешения, например class_name::member_name.

4.      Если вы объявляете общую статическую функцию-элемент, ваша программа может вызывать эту функцию, даже если объекты данного класса не существуют. Для вызова данной функции программа должна использовать оператор глобального разрешения, например menu::clear_screen().


Поиск

Loading

Оценка материала

...

Смотреть kino онлайн


Смотреть русское с разговорами видео

Online video HD

Видео скачать на телефон

Русские фильмы бесплатно

Full HD video online

Смотреть видео онлайн

Смотреть HD видео бесплатно

School смотреть онлайн