Прежде чем мы начнем изучать классы, давайте разберемся а для чего они вообще нужны. Ведь объектно-ориентированное программирование на несколько порядков сложнее, чем все чем до этого занимались. С одной стороны это так. Гораздо проще придумать название переменной, объявить ее с нужным типом и сразу же начать использовать ее в своей программе, чем разрабатывать класс. Ведь класс сначала нужно спроектировать, затем написать его код, да использование объектов отличается от всего, чем мы занимались раньше...
Как я уже писал раньше язык С++ является языком профессиональных программистов. Он создавался не как учебный язык, а язык на котором будут писаться профессиональные программы. С++ создан для обработки огромных объемов информации группами профессиональных программистов. Чтоб понять насколько серьезна проблема, представьте сколько информации приходиться хранить операторам сотовой связи. Кроме персональных данных (имя, фамилия, отчество, номер паспорта и т. д.), им приходится хранить тарифный план клиента, количество денег на счету клиента. И таких клиентов не один и не два, и даже не десяток и не сотня. И если бы программы были написаны так же, как мы делали это раньше, то прежде чем подключить нового клиента, мы были бы вынуждены попросить программиста создать новые переменные для хранения данных о новом клиенте, потом все перекомпилировать и только потом подключать его. Согласитесь перспектива не из радостных.
Но у объектно-ориентированного программирования кроме минусов, к которым относится сложность программ, есть и плюсы. И одним из них является возможность многократного использования кода, без какого либо изменения. То есть однажды создав какой-либо класс вы можете в дальнейшем включать его в свои программы без каких-либо изменений. На практике это выглядит как копирование нескольких файлов в папку с проектом. Согласитесь это удобно, когда для создания программы мы пользуемся готовыми решениями, вместо того, чтоб создавать их с нуля. Именно с помощью этих возможностей появилась возможность создавать новые версии таких программ как Adobe Photoshop или 3d Max. При этом новая версия программы не разрабатывается с нуля, а расширяется новыми функциями. За счет этого время затраченное на разработку объектно-ориентированных программ значительно сокращается.
И так объяснив зачем нам нужно объектно-ориентированное программирование давайте разберемся, что такое класс и объект. И так класс это список того, что должно быть у объекта, и что со все этим можно сделать. Например если взять здорового человека, то у него должна быть голова, тело, две руки и две ноги. На каждой руке по пять пальцев и т. д. Руками можно двигать, брать различные предметы. Туловище может принимать различное положение. С помощью ног, человек может перемещаться в пространстве. Обратите внимание эти функции нужны человеку для достижение конкретных целей. У человека нет функции «виляние хвостом», т. к. у него его нет. Тоже самое и с классом. Функции нужны для того, чтоб достигать определенных целей, а не сами по себе. Все люди (если конечно не принимать в расчет половые различия) выглядят одинаково. Две руки две ноги и т. д. Конкретный человек это объект, а человек вообще это класс. Но заметьте человек напрямую может управлять только к своим руками и ногами. Мы можем шевелить только своими руками, ногами, туловищем. Напрямую они не другому человеку. Чтоб использовать их извне мы должны физически это сделать (толкнуть, взять человека за руку) и т. д. На прямую они доступны только самому объекту. Если бы мы говорили о объекте в языке С++, то мы сказали что это закрытые данные. Теперь давайте создадим простой класс. Конечно практическая ценность этого класса равна нулю, но наша задача не бросить вызов Microsoft или Apple, а научиться работать с классами. И так вот код нашего простого класса:
class NameСlass
{
};
Как видим определение класса начинается со слова class за которым следует имя класса. Считается хорошим тоном программирования начинать названия класса с заглавной буквы. Затем фигурные скобки после которых в обязательно нужно поставить точку с запятой. Если этого не сделать, то программа не скомпилируется.
Теперь когда мы знаем как объявляется класс, создадим класс для работы с двумя числами. С помощью функций которые мы объявим в классе можно будет производить простые арифметические операции, сложение, вычитание и деление. И так наш класс:
#include <iostream>
#include <windows.h>
using namespace std;
class Math
{
public:
void setNum1()
{
cout << "Введите num1: ";
cin >> num1;
cout << "\n";
}
void setNum2()
{
cout << "Введите num2: ";
cin >> num2;
}
float add()
{
result = num1 + num2;
cout << result << endl;
}
float substract()
{
result = num2 - num1;
cout << result << endl;
}
float multiply()
{
result = num2 * num1;
cout << result << endl;
}
float divide()
{
result = num2 / num1;
cout << result << endl;
}
private:
float num1;
float num2;
float result;
};
int main()
{
Math object1, object2, object3, object4;
cout << "\nУстанавливаем значения num1 и num2 для созданных объектов.\n\n";
cout << "object1: \n\n";
object1.setNum1();
object1.setNum2();
cout << "object2: \n\n";
object2.setNum1();
object2.setNum2();
cout << "object3: \n\n";
object3.setNum1();
object3.setNum2();
cout << "object4: \n\n";
object4.setNum1();
object4.setNum2();
cout << "\Вызываем функцию add для наших объектов.\n\n";
cout << "\nРезультат выполнения object1.add()\n\n";
object1.add();
cout << "\nРезультат выполнения object2.add()\n\n";
object2.add();
cout << "\nРезультат выполнения object3.add()\n\n";
object3.add();
cout << "\nРезультат выполнения object4.add()\n\n";
object4.add();
cout << "\n Вызываем функцию substract для наших объектов.\n\n";
cout << "\nРезультат выполнения object1.substract()\n\n";
object1.substract();
cout << "\nРезультат выполнения object2.substract()\n\n";
object2.substract();
cout << "\nРезультат выполнения object3.substract()\n\n";
object3.substract();
cout << "\nРезультат выполнения object4.substract()\n\n";
object4.substract();
cout << "\n Вызываем функцию multiply для наших объектов.\n\n";
cout << "\nРезультат выполнения object1.multiply()\n\n";
object1.multiply();
cout << "\nРезультат выполнения object2.multiply()\n\n";
object2.multiply();
cout << "\nРезультат выполнения object3.multiply()\n\n";
object3.multiply();
cout << "\nРезультат выполнения object4.multiply()\n\n";
object4.multiply();
cout << "\n\n";
system("PAUSE");
return 0;
}
Прежде чем пойти дальше, я хотел бы пояснить несколько моментов. Как видим в нашем классе мы использовали два слова public и private. Слова public означает, что все данные объявленные после этого слова доступны в любом месте программы. Слово private означает что эти данные могут использовать только функции объявленные в этом же классе. Например нельзя изменить значение переменных объявленных после данных напрямую. Следующий код вставленный в предыдущую программу вызовет ошибку:
object1.num1 = 20;
Для чего это нужно? Давайте представим, что мы пишем программу, в которой пользователь вводит вручную вводит часы, минуты и секунды. Мы как программисты знаем, что часы, минуты или секунды не могут быть отрицательными а секунды могут находиться в интервале от 0 до 59. Поэтому прежде чем принять введенное пользователем значение мы проверяем его и если оно в допустимом диапазоне принимаем, если нет то выводим сообщение об ошибки. Но что мешает программисту записать где-нибудь в коде примерно следующее:
object1.seconds = -1245;
Если перемененная seconds будут объявлена после слова private в классе, то при компиляции будет выдано сообщение об ошибке что данные являются закрытыми, и напрямую к ним доступа нет. В объектно-ориентированном программировании это называется инкапсуляцией.
Конечно ничто не мешает программисту сделать эту переменную открытой, но тогда он берет всю ответственность на себя.
И второе, чтоб получить доступ к данным объекта мы должны после имени объекта поставить точку и обратиться и вызвать нужную нам функцию (функции объявленные в классе также называю методами). А что-бы объявить объект мы должны перед его именем поставить имя класса.
Если вам эта программа кажется надуманной и слишком сложной, подумайте вот о чем, когда начальник цеха пишет заявку на рабочих он не пишет, что у них должны быть две руки, две ноги и что они должны уметь делать. Он просто пишет, что ему нужны два сварщика, два слесаря и три подсобных рабочих. А все остальное подразумевается. Точно также и с классами. Когда мы создали класс мы можем не беспокоится о том, чтобы объекты содержали нужное нам количество перемененных и нужных типов. Компилятор сделает это автоматически.
Так же как и с переменными можно создавать массивы состоящие из объектов. Вот пример программы в которой объявлен массив из четырех объектов типа Math:
#include <iostream>
#include <windows.h>
using namespace std;
class Math
{
public:
void setNum1()
{
cout << " Введите num1: ";
cin >> num1;
cout << "\n";
}
void setNum2()
{
cout << " Введите num2: ";
cin >> num2;
cout << "\n";
}
float add()
{
result = num1 + num2;
cout << result << endl;
}
float substract()
{
result = num2 - num1;
cout << result << endl;
}
float multiply()
{
result = num2 * num1;
cout << result << endl;
}
float divide()
{
result = num2 / num1;
cout << result << endl;
}
private:
float num1;
float num2;
float result;
};
int main()
{
Math object[4];
for(int i = 0; i < 4 ; i++)
{
cout << "\nУстанавливаем значения num1 и num2"
<< " для созданных объектов.\n\n";
cout << "object[" << i << "] \n\n";
object[i].setNum1();
object[i].setNum2();
}
for(int i = 0; i < 4 ; i++)
{
cout << "\nВызываем функцию add для созданных объектов.\n\n";
cout << "\n Результат выполнения object[" << i << "].add()\n\n";
object[i].add();
}
for(int i = 0; i < 4 ; i++)
{
cout << "\nВызываем функцию substract для созданных объектов.\n\n";
cout << "\n Результат выполнения object[" << i << "].substract()\n\n";
object[i].substract();
}
for(int i = 0; i < 4 ; i++)
{
cout << "\nВызываем функцию multiply для созданных объектов.\n\n";
cout << "Результат выполнения object[" << i << "].multiply()\n\n";
object[i].multiply();
}
cout << "\n\n";
system("PAUSE");
return 0;
}
Как видим результат почти тот же самый. В следующем уроке мы продолжим тему классов.