Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...
Топ:
Особенности труда и отдыха в условиях низких температур: К работам при низких температурах на открытом воздухе и в не отапливаемых помещениях допускаются лица не моложе 18 лет, прошедшие...
Генеалогическое древо Султанов Османской империи: Османские правители, вначале, будучи еще бейлербеями Анатолии, женились на дочерях византийских императоров...
Интересное:
Уполаживание и террасирование склонов: Если глубина оврага более 5 м необходимо устройство берм. Варианты использования оврагов для градостроительных целей...
Наиболее распространенные виды рака: Раковая опухоль — это самостоятельное новообразование, которое может возникнуть и от повышенного давления...
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Дисциплины:
2021-06-23 | 24 |
5.00
из
|
Заказать работу |
|
|
Нами был разработан класс Рerson. И мы можем установить значения для переменных класса Person, можем получить их значения во внешние переменные. Однако если мы попробуем получить значения переменных name и age до их установки, то результаты будут неопределенными:
1 2 | Person person; cout << "Name: " << person.name << "\tAge: " << person.age << endl; |
Чтобы избежать подобной ситуации применяются специальные функции инициализации или конструкторы. Они позволяют инициализировать объект класса. Так, изменим код программы следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <iostream> #include <string> using std::string; using std::cout; using std::endl; class Person { public: string name; int age; Person(string n, int a) { name = n; age = a; } void move() { cout << name << " is moving" << endl; } }; int main () { Person person = Person("Tom", 22); cout << "Name: " << person.name << "\tAge: " << person.age << endl; person.name = "Bob"; person.move(); return 0; } |
Теперь в классе Person определен конструктор:
1 2 3 4 | Person(string n, int a) { name = n; age = a; } |
По сути конструктор представляет функцию, которая может принимать параметры и которая должна называться по имени класса. В данном случае конструктор принимает два параметра и передает их значения полям name и age.
Если в классе определены конструкторы, то при создании объекта этого класса необходимо вызвать один из его конструкторов.
Вызов конструктора получает значения для параметров и возвращает объект класса:
1 | Person person = Person("Tom", 22); |
После этого вызова у объекта person для поля name будет определено значение "Tom", а для поля age - значение 22. Вполедствии мы также сможем обращаться к этим полям и переустанавливать их значения.
|
Тажке можно использовать сокращенную форму инициализации:
1 | Person person("Tom", 22); |
По сути она будет эквивалетна предыдущей.
Консольный вывод определенной выше программы:
Name: Tom Age: 22Bob is movingПодобным образом мы можем определить несколько конструкторов и затем их использовать:
#include <iostream> #include <string> using std::string; using std::cout; using std::endl; class Person { public: string name; int age; Person(string n, int a) { name = n; age = a; } Person(string n) { name = n; age = 18; } Person() { name = "Bob"; age = 18; } void move() { cout << name << " is moving" << endl; } }; int main() { Person tom("Tom", 22); cout << "Name: " << tom.name << "\tAge: " << tom.age << endl; Person sam("Sam"); cout << "Name: " << sam.name << "\tAge: " << sam.age << endl; Person bob = Person(); cout << "Name: " << bob.name << "\tAge: " << bob.age << endl; return 0; } |
В классе Person определено три конструктора, и в функции все эти конструкторы используются для создания объектов:
Name: Tom Age: 22
Name: Sam Age: 18
Name: Bob Age: 18
Хотя пример выше прекрасно работает, однако мы можем заметить, что все три конструктора выполняют фактически одни и те же действия - устанавливают значения переменных name и age. И в C++ можем сократить их определения, вызова из одного конструктора другой и тем самым уменьшить объем кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Person { public: string name; int age; Person(string n, int a) { name = n; age = a; cout << "First constructor" << endl; } Person(string n): Person(n, 18) // вызов первого конструктора { cout << "Second constructor" << endl; } Person(): Person("Bob") // вызов второго конструктора { cout << "Third constructor" << endl; } void move() { cout << name << " is moving" << endl; } }; |
Запись Person(string n): Person(n, 18) представляет вызов конструктора, которому передается значение параметра n и число 18. То есть второй конструктор делегирует действия по инициализации переменных первому конструктору. При этом второй конструктор может дополнительно определять какие-то свои действия.
Таким образом, следующее создание объекта
1 | Person bob = Person(); |
будет использовать третий конструктор, который в свою очередь вызывает второй конструктор, а тот обращается к первому конструктору.
|
|
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...
История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!