- •1.Краткий обзор агрегатного типа struct.
- •Intcena;
- •Int main()
- •Int cena;
- •Void vyvod(avto s)
- •Int main()
- •3.Понятие объединения union.
- •Void vyvod(avto s, int I)
- •Int main()
- •Intcena;
- •Int main()
- •Int cena;
- •Intmain()
- •Void reset(); …
- •Void Demo::reset() // определениефункции reset( )
- •9.Пример реализации класса для организации обработки символьной строки.
- •Int demochar::length()
- •Int main()
- •10.Пример реализации класса для организации обработки одномерного массива целочисленных значений.
- •11.Инициализация объектов.
- •Int main()
- •12Указатель this.
- •13.Постоянные функции-члены класса.
- •3. Class avto {
- •15. Int main()
- •14.Массив объектов.
- •3. Class avto {
- •24. Int main() {
- •15.Статические переменные-члены и функции-члены класса.
- •17. Staticint GetSumCena() { return SumCena; };
- •19. Staticint SumCena;
- •16 Дружественные функции.
- •8. Friendvoid GetFields(avto&);
- •17 Класс, содержащий переменную-член типа класс.
- •3. Class Date_Avto {
- •16. Class avto {
- •30. Int main()
- •18 Сложность больших программных систем.
- •19 Пять признаков сложной системы.
- •20 Роль декомпозиции, абстракции, иерархии при построении сложных систем.
- •21 Объектная модель.
- •Ood основывается на объектно-ориентированной декомпозиции;
- •25Пример программы с наследованием классов.
- •3. Class avto {
- •18. Class gruz_avto : public avto {
- •36. Int main(){
- •26 Переопределение функций-членов внутри производного класса.
- •3. Class avto {
- •18. Class gruz_avto : public avto {
- •30. Int main()
- •5.Classint_Matrix// класс для обработки целочисленной матрицы
- •45. Int main()
- •Int main()
- •2. Usingnamespace std;
- •3. Int main()
- •18. Return 0;
- •Int main()
- •20. F.Write((char*)&s,sizeof(s));
- •7. Intcena;
- •21. F.Write((char*)&s,sizeof(s)); };
- •22. F.Close();
- •25. F.Seekg(sizeof(s), ios_base::beg);
- •26. F.Read((char*)&s,sizeof(s));
Int cena;
doublerashod;
};// !!! В конце описания класса обязательно пишется ;
// Определение явного конструктора
avto::avto()
{ cout << “Vvedite marku avto: ”; cin >> marka;
cout << “Vvedite cenu avto: ”; cin >> cena;
cout << “Vvedite rashod avto: ”; cin >> rashod;
}
// Определение явного деструктора
avto::~avto()
{ cout << “Marka avto:” << marka;
cout << “Cena avto:” << cena;
cout << “Rashod avto: ” << rashod;
cout << "RAZMER POLYA marka = " <<sizeof(marka) << endl;
cout << "RAZMER POLYA cena = " <<sizeof(cena) << endl;
cout << "RAZMER POLYA rashod = " <<sizeof(rashod) << endl;
}
Intmain()
{ avtoA1; // вызываются неявный, а затем явный конструкторы
cout <<"RAZMER A1 = "<<sizeof(A1) << endl;
return 0;
} // вызываются явный, а затем неявный деструкторы
!!! Если в текст рассмотренной выше программы внести единственное изменение, и вместо служебного слова class написать struct, то программа будет работать!!!
6.Особенность типа struct в языке C++.
!!! В языке С++ агрегатный тип struct устроен абсолютно также, как и тип class, с тем лишь отличием, что внутри класса все элементы по умолчанию имеют тип доступа private, а внутри структуры – public.
Особенностью использования структур в С++ является, во-первых, возможность включения в структуру функций-членов, и, во-вторых, то, что некоторая часть структур может быть сокрыта. В языке С такого не было.
Объявление функции-члена структуры включается в объявление структуры. Для обращения к такой функции в дальнейшем можно использовать конструкцию с оператором. (точка).
Идея включения в состав структур функций-членов заключается в том, что функциональность, необходимая для работы с типом данных struct, должна быть прямо включена в объявление структуры.
Функции-члены записываются также как и обычные, но эти функции могут напрямую обращаться к переменным-членам структуры без указания имени структуры.
Внутри объявления типа struct можно объявить только прототип функции, а определение размещать вне описания структурного типа. В этом случае в заголовке функции необходимо использовать дополнительно имя структурного типа и оператор разрешения области видимости:: .
Например: struct Demo { …
Void reset(); …
};
Void Demo::reset() // определениефункции reset( )
{ тело функции reset }
По умолчанию после определения структуры любой пользователь имеет возможность доступа ко всем членам и может модифицировать их нежелательным образом. Чтобы избежать этого, можно определять закрытые и открытые члены структуры, т.е. разрешается производить сокрытие данных.
Замечание: Рекомендуют использовать структуры только тогда, когда они объединяют переменные-члены, а в остальных случаях предпочтение отдавать классам.
7.Простой пример реализации класса в языке C++.
// Пример программы, в которой определяется класс avto,
// содержащий три поля. Демонстрируется использование
// "открытых" (public) функций-членов для обеспечения
// выполнения операций обработки "закрытых" (private)
// переменных-членов класса.
#include<iostream>
usingnamespace std;
class avto
{ public:
void input_avto(); // прототипметода input_avto()
void output_avto(); // прототипметода output_avto()
private:
char marka[15];
int cena;
doublerashod;
}; // !!! В конце описания класса обязательно пишется ;
// Определение функции-члена (метода) input_avto() класса avto
void avto::input_avto()
{
cout <<"START METHOD input_avto !!!"<< endl;
cout <<"Vvedite marku avto: "; cin >> marka;
cout <<"Vvedite cenu avto: "; cin >> cena;
cout <<"Vvedite rashod avto: "; cin >> rashod;
cout <<"FINISH METHOD input_avto !!!\n"<< endl;
}
// Определение функции-члена (метода) output_avto() класса avto
void avto::output_avto()
{ cout <<"START METHOD input_avto !!!"<< endl;
cout <<"Marka avto:"<< marka << endl;
cout <<"Cena avto:"<< cena << endl;
cout <<"Rashod avto:"<< rashod << endl;
cout <<"RAZMER POLYA marka = "<<sizeof(marka) << endl;
cout <<"RAZMER POLYA cena = "<<sizeof(cena) << endl;
cout <<"RAZMER POLYA rashod = "<<sizeof(rashod) << endl;
cout <<"FINISH METHOD input_avto !!!\n"<< endl;
}
int main()
{ avto A1; // срабатывает неявный конструктор класса avto
A1.input_avto(); // вызывается функция-член input_avto()
cout <<"RAZMER A1 = "<<sizeof(A1) << endl << endl;
A1.output_avto();// вызываетсяфункция-член input_avto()
return 0;
} // срабатывает неявный деструктор класса avto
При вызове функции main() выполняется следующая последовательность действий:
выполняется неявный конструктор класса avto и формируется объект A1;
вызывается и выполняется метод input_avto() класса avto;
выводится размер в байтах объекта A1;
вызывается и выполняется метод output_avto() класса avto;
выполняется неявный деструктор класса avto().
8.Пример использования класса и объектов в языке C++.
Класс представляет собой определяемый пользователем тип данных, а определяемые на основе такого типа переменные называют объектами.
Рассмотрим пример программы, в которой определяется класс avto и, на его основе демонстрируются варианты работы с тремя объектами a,b,c.
Класс avto будет иметь три поля: 1) name для размещения марки автомобиля; 2) cena для размещения цены автомобиля; 3) rashodдля размещения значения расхода топлива на 100 километров пробега. Для всех трех полей предусматривается закрытый режим доступа private:.
В классе avto предусматриваются три явных перегружаемых конструктора и явный деструктор.
Первый явный конструктор не имеет параметров. Этот вариант явного конструктора в поле cena записывает 5000, а в поле name записывает Lada.
Второй явный конструктор имеет один целочисленный параметр типа int. В результате выполнения этого варианта конструктора значение параметра записывается в поле cena.
Третий явный конструктор имеет два целочисленных параметра типа int. Первый параметр определяет значение базовой цены автомобиля, а второй – повышающий коэффициент для вычисления цены автомобиля. Этот конструктор формирует окончательное значение цены и записывает его в поле cena.
Явный деструктор предусматривает вывод сообщения об уничтожении объекта, об адресе и размере поля name.
Три функции-члена с именами, начинающимися с трех символов set, обеспечивают доступ к трем закрытым (private:) полям класса и предусматривают запись в эти поля соответствующих значений.
Три функции-члена с именами, начинающимися с трех символов get, обеспечивают доступ к трем закрытым полям класса и предусматривают чтение из полей хранящихся значений.
1. #include<iostream>
2. usingnamespace std;
3. class avto {
4. public:
5. avto(); // 1-йконструктор
6. avto(int); // 2-йконструктор
7. avto(int, int); // 3-й конструктор
8. ~avto(); // деструктор
9. void setname(char* name1){ name=name1;}
10. void setcena(int cena1) {cena=cena1;}
11. void setrashod(double rashod1) {rashod=rashod1;}
12. int getcena() {return cena;}
13. char* getname() {return name;}
14. double getrashod() {return rashod;}
15. private:
16. char* name;
17. int cena;
18. double rashod;
19. };
20. avto::avto() {cena=5000; name="Lada";}
21. avto::avto(int p){cena=p;};
22. avto::avto(int p, int c) {cena=p+p*c/100;}
23. avto::~avto(){
24. cout <<"Object destroy! Address of name_avto is "
25. <<&name <<" Razmer "<<sizeof(name)
26. << endl; };
27. int main() {
28. char navto[15];
29. cout <<"Input marka avto : "; cin >> navto;
30. {
31. avto a(15000); a.setcena(15000+500);
32. a.setname(navto); a.setrashod(6.5);
33. cout << a.getcena() << endl << a.getname()
34. << endl << a.getrashod()<< endl;
35. }
36. avto a(12000,10),b,c;
37. a.setname(navto); a.setrashod(6.5);
38. cout << a.getcena() << endl << a.getname()
39. << endl << a.getrashod()<< endl;
40. b=avto(); b.setrashod(8.0);
41. cout << b.getcena() << endl << b.getname()
42. << endl << b.getrashod()<< endl;
43. c=a; c.setrashod(7.5);
44. cout << c.getcena() << endl << c.getname()
45. << endl << c.getrashod()<< endl;
46. return 0;
47. }
Объявления класса avto находится в строках с 3 по 19 включительно и заканчивается соответствующей закрывающей фигурной скобкой, за которой записывается обязательная точка с запятой.
В строках 5,6,7 размещены прототипы трех явных конструкторов, а в строках с 20 по 22 включительно находятся определения соответствующих перегружаемых вариантов явных конструкторов.
5. avto(); // 1-й конструктор
6. avto(int); // 2-й конструктор
7. avto(int, int); // 3-й конструктор
20. avto::avto() {cena=5000; name="Lada";}
21. avto::avto(int p){cena=p;};
22. avto::avto(int p, int c) {cena=p+p*c/100;}
Отметим, что для конструкторов не нужно указывать тип возвращаемого значения, а имя явного конструктора всегда совпадает с названием соответствующего класса. В С++ допускается перегрузка явных конструкторов (по аналогии с перегрузкой функций). В данной программе соответствующие конструкторы отличаются списком параметров. В частности, в строке 20 определяется явный конструктор без параметров, в котором поле cena получает значение 5000, а названию автомобиля в поле name записывается Lada. В строке 21 определяется еще один вариант явного конструктора, в котором полю cena присваивает передаваемое значение.
В строке 31 инструкция avtoa(15000); определяет объект a класса avto путем вызова сначала неявного конструктора, который формирует заготовку объекта, и после этого сразу же автоматически вызывается явный конструктор из 21 строки, который в поле a.cena записывает значение 15000.
31. avtoa(15000); a.setcena(15000+500);
!!! Итак, при объявлении объекта сразу же, автоматически, запускаются неявный конструктор и далее соответствующий вариант явного конструктора, при условии, что такой предусматривается.
В строке 36 с помощью сначала вызова неявного конструктора, а затем конструктора из 20 строк доопределяются объекты с именами b и c, а с помощью конструктора из 22 строки доопределяется объект a. Второй параметр этого явного конструктора в данном примере определяет процент увеличения цены автомобиля.
36. avtoa(12000,10),b,c;
!!! Обратим внимание на то, что в 31 и 36 строках определены два объекта с именами a, причем используются при этом разные варианты конструктора. В данном случае строки с 31 по 35 включительно заключены в фигурные скобки, а потому соответствующее объявление объекта a носит локальный характер. Если скобки удалить, то будет возникать ошибка, поскольку тогда в программе будет проводиться попытка определения двух объектов с одинаковыми именами.
В языке С++ допускается отсутствие соответствующих объявлений конструкторов при описании класса. В этом случае создается и используется только неявный конструктор (иногда говорят конструктор по умолчанию), который не имеет параметров. Таким образом, в программе можно изъять строки 5-7, 20-22, заменить в 31 avtoa(15000); на avtoa; и в 36 строке avto a (12000,10),b,c; на avtoa,b,c; и программа должна работать.
Явный деструктор представляет собой специальную функцию-член класса, имя которой начинается с~ (тильда) с последующим указанием имени класса. Деструктор вызывается автоматически при выходе из блока, в котором был объявлен объект. Деструктор также вызывается в том случае, когда оператор delete применяется к указателю на именующий деструктор объект или в случае, когда он необходим для удаления подобъекта уничтожаемого объекта. Если предусматривается явный деструктор, то он вызывается перед неявным деструктором, который всегда формируется для соответствующего класса. Следовательно, в приведенном примере можно убрать 8 стр., 23-26 стр. Тогда будет определен только неявный деструктор.
В нашем примере определен явный деструктор, который при его выполнении будет выдавать сообщение
Object destroy! Address of name_avto is адресполя name объекта
Razmerразмер объекта
Обратим внимание на специфику выполнения конструктора в стр. 40. В языке С++ допустим оператор присваивания b=avto();. В этом случае сначала для объекта b выполнятся явный деструктор, далее неявный деструктор, а затем вновь сначала неявным, а потом явным конструктором будет создан объект b.
40. b=avto(); b.setrashod(8.0);
В представленном примере реализованы три функции-члена, имена которых начинаются с set. Все они используются для записи значений переменным-членам класса avto. С помощью трех функций-членов, имена которых начинаются с get, можно получать соответствующие значения.
9. void setname(char* name1){ name=name1;}
10. void setcena(int cena1) {cena=cena1;}
11. void setrashod(double rashod1) {rashod=rashod1;}
12. int getcena() {return cena;}
13. char* getname() {return name;}
14. doublegetrashod() {returnrashod;}
В стр. 43 приводится пример операции присваивания c=a, которая допустима в языке С++.
43. c=a; c.setrashod(7.5);
Рассмотрим начальный фрагмент функции main(), в котором в строках 27-28 определяется символьный массив navto[15], и далее вводится марка автомобиля.
27. int main() {
28. char navto[15];
29. cout <<"Input marka avto : "; cin >> navto;
30. {
31. avto a(15000); a.setcena(15000+500);
32. a.setname(navto); a.setrashod(6.5);
33. cout << a.getcena() << endl << a.getname()
34. <<endl<<a.getrashod()<<endl;
35. }
В строках 30-35 определен блок, заключенный в фигурные скобки. В 31 строке на основе второго конструктора создается объект a. Далее с помощью методов setcena(), setname(), setrashod() в строках 31-32 записываются соответствующие значения в поля cena, name, rashod. В 33-34 строках предусмотрен вывод этих значений на экран. В 35 строке блок завершается, а потому завершается существование объекта a, и в этот момент автоматически запускается сначала явный деструктор и далее неявный деструктор окончательно убирает объект из памяти.
В заключительном фрагменте функции main() демонстрируются некоторые приемы работы с тремя объектами (экземплярами класса)a,b,c.
36. avto a(12000,10),b,c;
37. a.setname(navto); a.setrashod(6.5);
38. cout << a.getcena() << endl << a.getname()
39. << endl << a.getrashod()<< endl;
40. b=avto(); b.setrashod(8.0);
41. cout << b.getcena() << endl << b.getname()
42. << endl << b.getrashod()<< endl;
43. c=a; c.setrashod(7.5);
44. cout << c.getcena() << endl << c.getname()
45. << endl << c.getrashod()<< endl;
46. return 0;
47. }// Трижды вызываются деструкторы для объектов a,b,c