C++. Классы. Часть 2. Конструктор класса. Особенности использования конструкторов в классах. Конструктор по умолчанию. Параметризированные конструкторы. Примеры классов, содержащих конструкторы
В данной теме рассматривается понятие конструктора на примере unmanaged ( native ) классов. Материалы данной темы также касаются и конструкторов managed- классов.
Поиск на других ресурсах:
1. Что называется конструктором класса? Какое назначение конструктора?
Класс может содержать специальные функции: конструкторы и деструкторы .
Конструктор класса – это специальный метод (функция) класса. Конструктор вызывается при создании объекта класса. Как правило, конструктор используется для:
- выделения памяти под объект класса;
- начальной инициализации внутренних данных класса.
Конструктор предназначен для формирования экземпляра объекта класса. Имя конструктора класса совпадает с именем класса.
2. В какой момент работы программы осуществляется вызов конструктора класса?
Вызов конструктора осуществляется при создании объекта класса. Конструктор класса вызывается компилятором.
3. Может ли конструктор иметь параметры? Примеры конструкторов с разным количеством параметров
Конструктор может иметь любое количество параметров. Также конструктор может быть без параметров (конструктор по умолчанию).
Пример. Объявляется класс CMyDate , определяющий дату (число, месяц, год). В классе объявлены два конструктора. Один конструктор без параметров, другой конструктор, получающий три параметра, которые устанавливают новую дату.
Объявление класса и его методов имеет вид
// класс, который определяет дату class CMyDate < int day; int month; int year; public: // конструкторы класса CMyDate(); // конструктор без параметров CMyDate(int d, int m, int y); // конструктор с тремя параметрами // методы класса void SetDate(int d, int m, int y); // установить новую дату int GetDay(void); // возвращает номер дня int GetMonth(void); // возвращает номер месяца int GetYear(void); // возвращает год >; // реализация конструкторов и методов класса // конструктор без параметров (конструктор по умолчанию) CMyDate::CMyDate() < // установить дату 01.01.2001 day = 1; month = 1; year = 2001; > // конструктор с тремя параметрами CMyDate::CMyDate(int d, int m, int y) < day = d; month = m; year = y; >// Установить новую дату void CMyDate::SetDate(int d, int m, int y) < day = d; month = m; year = y; >// возвратить номер дня int CMyDate::GetDay(void) < return day; > // возвратить номер месяца int CMyDate::GetMonth(void) < return month; > // возвратить год int CMyDate::GetYear(void) < return year; >
Демонстрация вызова конструкторов при объявлении объектов класса
CMyDate MD1; // вызывается конструктор без параметров CMyDate MD2(4, 5, 2008); // вызывается конструктор с тремя параметрами int t; t = MD1.GetDay(); // t = 1 t = MD1.GetYear(); // t = 2001 t = MD2.GetMonth(); // t = 5 t = MD2.GetYear(); // t = 2008
4. Обязательно ли в классе описывать конструктор?
Не обязательно. При создании объекта класса, который не содержит ни одного конструктора, будет вызываться неявно заданный конструктор по умолчанию (default constructor), выделяющий память для объекта класса. Однако, в классе можно объявить собственный конструктор по умолчанию. Такой конструктор называется: явно заданный конструктор по умолчанию.
5. Что такое конструктор по умолчанию ( default constructor )? Примеры
Конструктор по умолчанию – это конструктор класса, который объявляется без параметров. Если класс не содержит явным образом определенный конструктор, тогда при создании объекта автоматически вызывается конструктор по умолчанию. Конструктор по умолчанию просто выделяет память для объекта класса, если он объявляется.
Пример 1. Пусть задан класс CMyPoint , определяющий точку на координатной плоскости. В классе не реализовано ни одного конструктора.
// класс, который определяет точку на координатной плоскости class CMyPoint < int x; int y; public: // методы класса void SetPoint(int nx, int ny) < x = nx; y = ny; >int GetX(void) < return x; > int GetY(void) < return y; > >;
Однако, при создании объекта класса компилятор автоматически вызовет конструктор по умолчанию.
CMyPoint MP; // автоматически вызовется конструктор по умолчанию MP.SetXY(4, -10); // вызов методов класса int t; t = MP.GetY(); // t = -10
Конструктор по умолчанию автоматически вызовется только тогда, если в классе не объявлено ни одного конструктора. Как только в классе объявить любой другой конструктор с параметрами, то при объявлении
CMyPoint MP;
компилятор выдаст ошибку.
Пример 2. Модификация класса CMyPoint . В классе присутствует явно заданный конструктор по умолчанию.
// класс, который определяет точку на координатной плоскости class CMyPoint < int x; int y; public: // явно заданный конструктор по умолчанию CMyPoint() < x = y = 0; > // методы класса void SetPoint(int nx, int ny) < x = nx; y = ny; >int GetX(void) < return x; > int GetY(void) < return y; > >;
Демонстрация вызова явным образом заданного конструктора по умолчанию
CMyPoint MP; // вызовется явно заданный конструктор по умолчанию int t; t = MP.GetX(); // t = 0
6. Сколько конструкторов по умолчанию может иметь класс?
Каждый класс может иметь только один конструктор по умолчанию. Это связано с тем, что в классе не может быть двух методов (функций) с одинаковой сигнатурой.
7. Может ли конструктор возвращать значение?
Конструктор не может возвращать значения (даже значение void ). Если в конструкторе написать возвращение значения с помощью оператора return , то компилятор выдаст ошибку.
8. Пример объявления и использования класса, который содержит несколько конструкторов. Реализация типа string в классе
Например, нужно объявить класс, который содержит информацию об имени работника и его возраст.
Для представления внутренних членов данных в классе используется тип string . Чтобы использовать тип string в программах на Visual C++, нужно в начале модуля, который описывает класс, подключить библиотеку < string >и пространство имен std
#include using namespace std;
// Класс, который определяет общие данные о клиенте class CName < string name; // Фамилия string surname; // имя string patronymic; // отчество int age; // возраст public: CName(void); // конструктор без параметров CName(string n_name, string n_sname); // конструктор с двумя параметрами CName(string n_name, string n_sname, string n_patr); // конструктор с тремя параметрами CName(string n_name, string n_sname, string n_patr, int n_age); // 4 параметры // внутренние методы класса - реализованы в объявлении класса string GetName(void) < return name; > string GetSurname(void) < return surname; > string GetPatr(void) < return patronymic; > int GetAge(void) < return age; > ~CName(void); // деструктор >;
Реализация конструкторов и деструктора класса
// реализация конструкторов и деструктора класса // конструктор без параметров CName::CName(void) < name = «»; surname = «»; patronymic = «»; age = 0; > // конструктор с двумя параметрами CName::CName(string n_name, string n_sname) < name = n_name; surname = n_sname; patronymic = «»; age = 0; > // конструктор с тремя параметрами CName::CName(string n_name, string n_sname, string n_patr) < name = n_name; surname = n_sname; patronymic = n_patr; age = 0; >// конструктор с 4 параметрами CName::CName(string n_name, string n_sname, string n_patr, int n_age) // 4 параметра < name = n_name; surname = n_sname; patronymic = n_patr; age = n_age; >CName::~CName(void)
9. Как работает конструктор класса в случае, когда в классе объявлен объект другого класса (подобъект)? Пример
- первым вызывается конструктор (конструкторы) класса, который есть подобъектом включающего класса;
- следующим вызывается конструктор включающего класса.
Пример. Пусть заданы 2 класса: CMyPoint , CMyLine . В классе CMyLine есть два подобъекта класса CMyPoint . При создании объекта класса CMyLine , сначала будут вызваны 2 конструктора класса CMyPoint для двух подобъектов, а потом вызовется конструктор класса CMyLine .
// класс CMyPoint class CMyPoint < int x, y; public: CMyPoint(void); // конструктор класса >; // конструктор класса CMyPoint CMyPoint::CMyPoint(void) < // . > // класс CMyLine class CMyLine < CMyPoint p1; CMyPoint p2; public: CMyLine(void); >; // конструктор класса CMyLine CMyLine::CMyLine(void) < // . >
Объявление объекта класса CMyLine
CMyLine ML; // вызовутся: 1 - два конструктора CMyPoint(), 2 - конструктор CMyLine()
После такого объявления конструкторы вызовутся в следующей последовательности:
- CMyPoint::CMyPoint() для объекта p1 класса CMyLine() ;
- CMyPoint::CMyPoint() для объекта p2 класса CMyLine() ;
- CMyLine::CMyLine() для объекта ML .
10. Как работает конструктор класса в случае, когда создается объект класса, который есть производным (унаследованным) от другого класса?
Если есть два класса, один из которых базовый а другой — унаследованный от базового, то в этом случае последовательность вызовов следующая:
- сначала вызовется конструктор базового класса;
- следующим вызовется конструктор унаследованного класса.
11. Может ли конструктор объявляться в разделе private ?
Да, может. Такой конструктор называется приватным конструктором (private constructor).
12. В каких случаях могут создаваться приватные конструкторы?
При объявлении обычного объекта класса, конструкторы, которые размещены в разделе private (приватные конструкторы), есть недоступными.
Доступ к созданию объектов с помощью приватных конструкторов имеют:
- методы, объявленные в классе (методы-члены класса). Сюда относятся также и статические методы, объявленные с ключевым словом static ;
- методы дружественных классов (дружественные методы).
13. Как будет работать программа, если попробовать создать объект класса, в котором объявлен приватный конструктор по умолчанию?
В этом случае будет ошибка компиляции.
Например. Пусть задан класс CMyDate . В классе определен явно заданный конструктор по умолчанию (без параметров).
class CMyDate < private: // явно заданный конструктор по умолчанию CMyDate() < // тело конструктора // . > >
Попытка создать объект класса приведет к ошибке компиляции
CMyDate MD; // ошибка компиляции
То же самое будет, если попробовать создать статический объект
static CMyDate MDS; // ошибка компиляции также для статического объекта
14. Может ли в классе быть объявлено два конструктора, которые принимают одинаковое количество параметров?
Да, может. Однако с условием, что типы параметров будут отличаться. Для класса должно выполняться правило:
- в классе не может быть двух методов (функций) с одинаковой (совпадающей) сигнатурой.
Этот вопрос тесно связан с темой перегрузки функций.
15. Какие конструкторы называются параметризованными?
Параметризованный конструктор – это конструктор класса, который имеет параметры.
16. Какие существуют способы инициализации членов объекта с помощью конструктора, который получает один параметр? Пример
Для конструктора, получающего один параметр существует два способа инициализации:
- инициализация по образцу вызова функции;
- инициализация по образцу оператора присваивания.
Пример. Пусть задан класс, в котором определяется одна переменная n типа int . Класс имеет два конструктора. Первый – конструктор без параметров, обнуляющий значение n . Второй – конструктор с одним параметром, устанавливающий новое значение n .
Общий вид объявления класса
class CMyInt < private: int n; // количество элементов массива public: CMyInt(void) < >; // конструктор по умолчанию ~CMyInt(void); // деструктор CMyInt(int nn) < n = nn; >// конструктор с одним параметром // методы класса void SetN(int nn) < n = nn; >int GetN(void) < return n; > >;
Объявить объект класса CMyInt с использованием конструктора с 1 параметром можно двумя способами
// Демонстрация объявления объекта класса, // если в классе реализован конструктор с 1 параметром CMyInt MI1(10); // вызов конструктора с 1 параметром CMyInt MI2 = 20; // то же самое, но другим способом int t; t = MI1.GetN(); // t = 10 t = MI2.GetN(); // t = 20
Связанные темы
- Понятие класса. Объявление класса. Объект класса. Классы в среде CLR . Инкапсуляция данных в классе
- Конструктор копирования.Примеры использования. Передача объекта класса в функцию. Возврат класса из функции
Что такое параметризированный конструктор с
В прошлой статье для создания объекта использовался конструктор по умолчанию. Однако мы сами можем определить свои конструкторы. Как правило, конструктор выполняет инициализацию объекта. При этом если в классе определяются свои конструкторы, то он лишается конструктора по умолчанию.
На уровне кода конструктор представляет метод, который называется по имени класса, который может иметь параметры, но для него не надо определять возвращаемый тип. Например, определим в классе Person простейший конструктор:
Person tom = new Person(); // Создание объекта класса Person tom.Print(); // Имя: Tom Возраст: 37 class Person < public string name; public int age; public Person() < Console.WriteLine("Создание объекта Person"); name = "Tom"; age = 37; >public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Итак, здесь определен конструктор, который выводит на консоль некоторое сообщение и инициализирует поля класса.
public Person()
Конструкторы могут иметь модификаторы, которые указываются перед именем конструктора. Так, в данном случае, чтобы конструктор был доступен вне класса Person, он определен с модификатором public .
Определив конструктор, мы можем вызвать его для создания объекта Person:
Person tom = new Person(); // Создание объекта Person
В данном случае выражение Person() как раз представляет вызов определенного в классе конструктора (это больше не автоматический конструктор по умолчанию, которого у класса теперь нет). Соответственно при его выполнении на консоли будет выводиться строка «Создание объекта Person»
Подобным образом мы можем определять и другие конструкторы в классе. Например, изменим класс Person следующим образом:
Person tom = new Person(); // вызов 1-ого конструктора без параметров Person bob = new Person("Bob"); //вызов 2-ого конструктора с одним параметром Person sam = new Person("Sam", 25); // вызов 3-его конструктора с двумя параметрами tom.Print(); // Имя: Неизвестно Возраст: 18 bob.Print(); // Имя: Bob Возраст: 18 sam.Print(); // Имя: Sam Возраст: 25 class Person < public string name; public int age; public Person() < name = "Неизвестно"; age = 18; >// 1 конструктор public Person(string n) < name = n; age = 18; >// 2 конструктор public Person(string n, int a) < name = n; age = a; >// 3 конструктор public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Теперь в классе определено три конструктора, каждый из которых принимает различное количество параметров и устанавливает значения полей класса. И мы можем вызвать один из этих конструкторов для создания объекта класса.
Консольный вывод данной программы:
Имя: Неизвестно Возраст: 18 Имя: Bob Возраст: 18 Имя: Sam Возраст: 25
Стоит отметить, что начиная с версии C# 9 мы можем сократить вызов конструктора, убрав из него название типа:
Person tom = new (); // аналогично new Person(); Person bob = new ("Bob"); // аналогично new Person("Bob"); Person sam = new ("Sam", 25); // аналогично new Person("Sam", 25);
Ключевое слово this
Ключевое слово this представляет ссылку на текущий экземпляр/объект класса. В каких ситуациях оно нам может пригодиться?
Person sam = new("Sam", 25); sam.Print(); // Имя: Sam Возраст: 25 class Person < public string name; public int age; public Person() < name = "Неизвестно"; age = 18; >public Person(string name) < this.name = name; age = 18; >public Person(string name, int age) < this.name = name; this.age = age; >public void Print() => Console.WriteLine($"Имя: Возраст: "); >
В примере выше во втором и третьем конструкторе параметры называются также, как и поля класса. И чтобы разграничить параметры и поля класса, к полям класса обращение идет через ключевое слово this . Так, в выражении
this.name = name;
первая часть — this.name означает, что name — это поле текущего класса, а не название параметра name. Если бы у нас параметры и поля назывались по-разному, то использовать слово this было бы необязательно. Также через ключевое слово this можно обращаться к любому полю или методу.
Цепочка вызова конструкторов
В примере выше определены три конструктора. Все три конструктора выполняют однотипные действия — устанавливают значения полей name и age. Но этих повторяющихся действий могло быть больше. И мы можем не дублировать функциональность конструкторов, а просто обращаться из одного конструктора к другому также через ключевое слово this , передавая нужные значения для параметров:
class Person < public string name; public int age; public Person() : this("Неизвестно") // первый конструктор < >public Person(string name) : this(name, 18) // второй конструктор < >public Person(string name, int age) // третий конструктор < this.name = name; this.age = age; >public void Print() => Console.WriteLine($"Имя: Возраст: "); >
В данном случае первый конструктор вызывает второй, а второй конструктор вызывает третий. По количеству и типу параметров компилятор узнает, какой именно конструктор вызывается. Например, во втором конструкторе:
public Person(string name) : this(name, 18)
идет обращение к третьему конструктору, которому передаются два значения. Причем в начале будет выполняться именно третий конструктор, и только потом код второго конструктора.
Стоит отметить, что в примере выше фактически все конструкторы не определяют каких-то других действий, кроме как передают третьему конструктору некоторые значения. Поэтому в реальности в данном случае проще оставить один конструктор, определив для его параметров значения по умолчанию:
Person tom = new(); Person bob = new("Bob"); Person sam = new("Sam", 25); tom.Print(); // Имя: Неизвестно Возраст: 18 bob.Print(); // Имя: Bob Возраст: 18 sam.Print(); // Имя: Sam Возраст: 25 class Person < public string name; public int age; public Person(string name = "Неизвестно", int age = 18) < this.name = name; this.age = age; >public void Print() => Console.WriteLine($"Имя: Возраст: "); >
И если при вызове конструктора мы не передаем значение для какого-то параметра, то применяется значение по умолчанию.
Первичные конструкторы
Начиная с версии C# 12 в язык C# была добавлена поддержка первичных конструкторов (Primary constructors). Первичные конструкторы позволяют добавлять параметры к определению класса и использовать эти параметры внутри класса:
var tom = new Person("Tom", 38); Console.WriteLine(tom); public class Person(string name, int age) < public Person(string name) : this(name, 18) < >public void Print() => Console.WriteLine($"name: , age: "); >
Здесь для класса Person определен первичный конструктор с двумя параметрами — name и age. Эти параметры применяются для используются в методе Print.
За кадром для каждого параметра первичного конструктора в классе создается приватное поле, которое хранит значение параметра. Благодаря этому они могут использоваться в теле класса.
Кроме первичных конструкторов класс может определять дополнительные конструкторы, как примере выше. Но эти дополнительные конструкторы должны вызывать первичный конструктор:
public Person(string name) : this(name, 18)
Инициализаторы объектов
Для инициализации объектов классов можно применять инициализаторы . Инициализаторы представляют передачу в фигурных скобках значений доступным полям и свойствам объекта:
Person tom = new Person < name = "Tom", age = 31 >; // или так // Person tom = new() < name = "Tom", age = 31 >; tom.Print(); // Имя: Tom Возраст: 31
С помощью инициализатора объектов можно присваивать значения всем доступным полям и свойствам объекта в момент создания. При использовании инициализаторов следует учитывать следующие моменты:
- С помощью инициализатора мы можем установить значения только доступных из вне класса полей и свойств объекта. Например, в примере выше поля name и age имеют модификатор доступа public, поэтому они доступны из любой части программы.
- Инициализатор выполняется после конструктора, поэтому если и в конструкторе, и в инициализаторе устанавливаются значения одних и тех же полей и свойств, то значения, устанавливаемые в конструкторе, заменяются значениями из инициализатора.
Инициализаторы удобно применять, когда поле или свойство класса представляет другой класс:
Person tom = new Person < name = "Tom", company = < title = "Microsoft">>; tom.Print(); // Имя: Tom Компания: Microsoft class Person < public string name; public Company company; public Person() < name = "Undefined"; company = new Company(); >public void Print() => Console.WriteLine($»Имя: Компания: «); > class Company
Обратите внимание, как устанавливается поле company :
company =
Деконструкторы
Деконструкторы (не путать с деструкторами) позволяют выполнить декомпозицию объекта на отдельные части.
Например, пусть у нас есть следующий класс Person:
class Person < string name; int age; public Person(string name, int age) < this.name = name; this.age = age; >public void Deconstruct(out string personName, out int personAge) < personName = name; personAge = age; >>
В этом случае мы могли бы выполнить декомпозицию объекта Person так:
Person person = new Person("Tom", 33); (string name, int age) = person; Console.WriteLine(name); // Tom Console.WriteLine(age); // 33
Значения переменным из деконструктора передаюся по позиции. То есть первое возвращаемое значение в виде параметра personName передается первой переменной — name, второе возващаемое значение — переменной age.
По сути деконструкторы это не более,чем более удобный способ разложения объекта на компоненты. Это все равно, что если бы мы написали:
Person person = new Person("Tom", 33); string name; int age; person.Deconstruct(out name, out age);
При получении значений из деконструктора нам необходимо предоставить столько переменных, сколько деконструктор возвращает значений. Однако бывает, что не все эти значения нужны. И вместо возвращаемых значений мы можм использовать прочерк _ . Например, нам надо получить только возраст пользователя:
Person person = new Person("Tom", 33); (_, int age) = person; Console.WriteLine(age); // 33
Поскольку первое возвращаемое значение — это имя пользователя, которое не нужно, в в данном случае вместо переменной прочерк.
Конструкторы в C#
Всем доброго времени суток. На связи Алексей Гулынин. В данной статье я бы хотел рассказать, что такое конструкторы в C#. В прошлой статье, посвященной классам в C# мы присваивали значения переменным объекта следующим образом:
Room myRoom = new Room(); //в начале создавали объект //затем инициализировали переменные myRoom.length = 7; myRoom.height = 2.5; myRoom.width = 4;
Данный способ является приемлемым, но не является оптимальным. Переменные необходимо определять в конструкторе класса .
Конструктор инициализирует объект при его создании, т.е. объект будет иметь заполненную структуру уже при создании. Конструктор имеет такое же имя, что и сам класс. По синтаксису похож на метод. В определении конструктора не указывается тип возвращаемого значения:
уровень_доступа имя_класса() < //тело конструктора >
В качестве уровня доступа обычно используется public , так как конструктор обычно вызывается вне класса. Все классы имеют конструкторы, независимо от того, создаёте вы его или нет ( C# автоматически создаёт конструктор по умолчанию). Данный конструктор инициализирует все переменные-члены, имеющие тип значений, нулями, а переменные ссылочного типа — null значениями. Давайте создадим свой собственный конструктор, на основе предыдущего примера:
public Room()
Если мы теперь создадим объект класса Room, то его поле length (поле объекта) будет уже иметь значение, равное 7:
Room newRoom = new Room(); Console.WriteLine(newRoom.length);//выведет 7
В нашем примере использовался конструктор без параметров. А что если мы захотим изменить длину нашей комнаты. Для этого придётся написать newRoom.length = 6. Чтобы этого не делать, используются параметризированные конструкторы . Параметры вносятся в конструктор точно также, как и в метод. Давайте создадим параметризированный конструктор для нашего класса Room :
public Room(double a, double b, double c, boolean d)
Давайте теперь создадим новый объект, передав в конструктор параметры:
Room newRoom = new Room(10,3,4,true); Console.WriteLine(newRoom.length); //выведет 10
При использовании оператора new объектам динамически выделяется память из пула свободной памяти. Данный объем свободной памяти не бесконечен. Есть риск возникновения ситуации, когда память под объект не будет выделена. Поэтому в схеме динамического выделения памяти есть механизм очистки от неиспользуемых объектов. Данный процесс может выполняться вручную (например в Javascript с помощью оператора delete ). В C# за это отвечает механизм сборки мусора, который не требует участия программиста.
В языке C# можно определить метод, который будет вызываться непосредственно перед тем, когда объект будет уничтожен (т.е. когда его настигнет сборщик мусора). Этот метод называется деструктор . Синтаксис его следующий:
~имя_класса () < //тело деструктора >
Деструктор вызывается только перед началом работы системы сбора мусора. Мы не можем знать точно, когда будет вызван деструктор, но точно знаем, что он будет вызван перед завершением работы программы. Для нашего примера деструктор будет иметь вид:
~Room()
В качестве домашнего задания: переделайте пример из предыдущей статьи только с использованием параметризированного конструктора.
В данной статье вы узнали, что такое конструкторы в C#.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.
Конструктор в C++ и типы конструкторов
Что такое конструктор C + +?
Конструктор в C++ — это специальная «ФУНКЦИЯ-ЧЛЕНА», имеющая то же имя, что и у его класса, которая используется для инициализации некоторых допустимых значений членов данных объекта. Он выполняется автоматически всякий раз, когда создается объект класса. Единственное ограничение, применимое к конструктору, заключается в том, что он не должен иметь тип возвращаемого значения или значение void. Это связано с тем, что конструктор автоматически вызывается компилятором и обычно используется для ИНИЦИАЛИЗАЦИИ ЗНАЧЕНИЙ. Компилятор отличает конструктор от других функций-членов класса по его имени, которое совпадает с именем его класса. ctorz — это аббревиатура конструктора в C++.
Конструктор C++ может быть определен как класс так же, как и обычные функции-члены, и может получить доступ к любому из своих элементов данных.
Конструктор в синтаксисе C++
Синтаксис для определения конструктора внутри тела класса следующий:
class CLASSNAME < ……… public : CLASSNAME([parameter_list]) // constructor definition < . . . . . . >. . . . . . . . >;
Вы также можете определить конструктор с его объявлением внутри тела класса и посмотреть, что будет дальше.
class CLASSNAME < . . . . . . . . public: CLASSNAME ([parameter_list]);//Constructor declaration . . . . . . . . . >; CLASSNAME: :CLASSNAME([parameter_list])//Constructor Definition
- Приведенный выше синтаксис показывает объявление и определение конструктора. Он определяется вне класса так же, как мы определяем функцию-член вне класса, используя оператор разрешения области видимости.
- Следует отметить, что имя конструктора совпадает с именем его класса. Список параметров конструктора, заключенный в квадратные скобки, является необязательным и может содержать ноль или более параметров.
- Мы должны объявить конструктор в общедоступном разделе класса, так как они вызываются автоматически при создании объектов.
С помощью примеров мы узнаем о конструкторе C++ и его типе в этой статье.
Когда объект создается, немедленно вызывается функция-член определенного типа, называемая конструктором.
Конструктор в C++ не имеет возвращаемого типа и имеет то же имя, что и класс. Например,
class Table < Public: Table()< >>;
Здесь цель Конструктор класса Table называется Table(). Обратите внимание, что конструктор.
- Конструктор имеет то же имя, что и класс.
- Конструктор не имеет возвращаемого типа, и
- Конструктор является общедоступным
Типы конструкторов в C++
В С++ есть 3 типа конструкторов:
- Конструктор по умолчанию
- Параметризованный конструктор
- Копировать конструктор
Конструктор по умолчанию
Конструктор, которому не передаются аргументы, называется конструктором по умолчанию. Его также называют конструктором без параметров.
Конструкторы — это функции класса, которые вызываются при создании новых экземпляров объектов класса. Конструкторы имеют то же имя, что и класс, но у них даже нет типа возвращаемого значения void. Они наиболее полезны для присвоения переменным класса их начальных значений. Конструкторы по умолчанию и параметризованные конструкторы — это два основных типа конструкторов.
Нет параметров, принимаемых конструкторами по умолчанию. Компилятор предоставит неявный конструктор по умолчанию, если программист не предоставит его явно. В этом сценарии значения переменных по умолчанию равны 0.
Используя конструктор по умолчанию, члены данных могут быть инициализированы некоторыми реалистичными значениями в его определении, даже если никакие аргументы не указаны явно. Каждый раз, когда создается объект, вызывается конструктор. Если мы определяем объекты и классы без определения какого-либо конструктора для класса. Таким образом, в такой ситуации компилятор автоматически генерирует собственный конструктор без каких-либо параметров, т.е. конструктор по умолчанию.
Этот компилятор создает конструктор по умолчанию, который вызывается автоматически при создании любого объекта класса, но не выполняет никакой инициализации. Однако если вы явно определяете конструктор по умолчанию, компилятор больше не создает для вас конструктор по умолчанию.
Ниже приведены ключевые моменты при определении конструкторов для класса:
- Конструктор имеет то же имя, что и класс, к которому он принадлежит.
- Если вы открыто не предоставляете собственный конструктор, компилятор создает для вас конструктор по умолчанию.
- Конструктор предпочтительно можно использовать для инициализации, а не для операций ввода/вывода.
- Конструкторы не могут быть статическими.
- Конструкторы также используются для поиска памяти во время выполнения с помощью оператора new.
- Конструкторы не могут быть виртуальными.
- Конструктор выполняется многократно всякий раз, когда создаются объекты класса.
- Мы можем объявить более одного конструктора в классе, т.е. конструкторы могут быть перегружены.
Программа в конструкторе по умолчанию
class Line < public: int size; //default constructor Line() < size=30; >>; int main() < //default constructor called when object is created Line l; cout
Output Line size is 30 cm
Конструктор для приведенного выше кода вызывается, как только объект создается для инициализации его элементов данных.
В приведенном выше примере мы предоставили конструктор по умолчанию без аргументов Line(); однако, если мы этого не сделаем, компилятор предоставит его, чтобы помочь в инициализации элементов данных.
#include using namespace std; class TestDefault < private: int num1, num2 ; public: TestDefault() < num1 = 10; num2 = 20; >void display() < coutOutput num1 = 10 num2 = 20
Параметризованный конструктор
Однако в отличие от конструкторов по умолчанию, которые не принимают никаких параметров, конструктору можно передать один или несколько аргументов.
Конструкторы, которые могут принимать аргументы, называются параметризованными конструкторами.
Синтаксис объявления параметризованного конструктора внутри набора:
class class_name < public: class_name(variables) //Parameterized constructor declared. < >>;
Синтаксис объявления параметризованной конструкции вне класса:
class class_name < >; class_name :: class_name() //Parameterized constructor declared.
Конструктор копирования в C ++
Конструктор копирования в С++ — это конструктор, который создает объект, инициализируя его ранее созданным объектом того же класса.
Перегрузка конструктора
В некоторых программах у класса был только один конструктор с нулевыми, одним или несколькими параметрами. Конструктор является ключевым для инициализации объекта. Механизм конструктора значительно мощнее за счет объединения с возможностью перегрузки. Это стало возможным благодаря предоставлению более одного конструктора в классе, называемом перегрузкой конструктора.
Пример перегрузки конструктора C++
/*. A program to feature the concept of constructor overloading. */ #include using namespace std; class ABC < private: int x,y; public: ABC () //constructor 1 with no arguments < x = y = 0; >ABC(int a) //constructor 2 with one argument < x = y = a; >ABC(int a,int b) //constructor 3 with two argument < x = a; y = b; >void display() < cout OUTPUT: X = 10 and y = 0 X = 10 and y = 10 x = 10 and y = 2
Конструктор в массиве объектов
Конструкторы вызываются для каждого объекта создаваемого класса. Всякий раз, когда определяется массив объектов класса, для каждого объекта массива вызывается конструктор по умолчанию.
Другими словами, каждый объект массива инициализируется одним и тем же набором значений с использованием конструктора аргументов по умолчанию.
Например:
Он определяет массив из 20 объектов класса прямоугольник. Каждый объект (элемент) прямоугольника массива вызывает конструктор по умолчанию для инициализации своих элементов данных. Мы также можем инициализировать значение для отдельных объектов массива явно, используя параметризованный конструктор, который показан ниже:
Три объекта r[0], r[1], r[2] создаются и инициализируются с помощью конструктора с двумя параметрами, поскольку передаются только два аргумента. Здесь конструктор с двумя параметрами вызывается явно для инициализации отдельных объектов массива.
Инициализировать массив объектов с параметризованными конструкторами в C++
Когда класс определен, указывается только спецификация объекта; память или емкость не выделяются. Вам нужно создавать объекты, чтобы использовать данные и функции доступа, указанные в классе.
Синтаксис:
Конкретные методы для инициализации списка объектов Parameterized Constructors:
Использование malloc(): используйте метод malloc(), чтобы избежать вызова непараметризованного конструктора. Метод «Malloc» или «Распределение памяти» в C++ используется для динамического выделения указанного размера одного большого блока памяти. Он возвращает своего рода пустой указатель, который можно бросить в указатель любого типа.
#include #define P 5 using namespace std; class Test < // private variables int a, b; public: // parameterized constructor Test(int a, int b) < this->a = a; this->b = b; > // function to print void print() < cout >; int main() < // allocating dynamic array // of Size N using malloc() Test* arr = (Test*)malloc(sizeof(Test) * P); // calling constructor // for each index of array for (int k = 0; k < P; k++) < arr[k] = Test(k, k + 1); >// printing contents of array for (int k = 0; k < P; k++) < arr[k].print(); >return 0; >
Output: 0 1 1 2 2 3 3 4 4 5
Рабочий двойной указатель
- Указатель на указатель представляет собой набор сложных косвенных или цепочек указателей. Указатель часто содержит адрес переменной. Когда мы рассказываем указатель указателю, первый указатель содержит адрес второго указателя, который указывает на место, содержащее реальное значение, как показано ниже.
- Теперь мы можем выделить несколько блоков для назначения, поэтому нам нужно вызвать параметризованный конструктор для инициализации каждого индекса с помощью нового ключевого слова.
#include #define T 10 using namespace std; class Test < // private variables int s, t; public: // parameterized constructor Test(int s, int t) : s(s), t(t) < >// function to print void print() < cout >; int main() < // allocating array using // pointer to pointer concept Test** arr = new Test*[T]; // calling constructor for each index // of array using new keyword for (int i = 0; i < T; i++) < arr[i] = new Test(i, i + 1); >// printing contents of array for (int i = 0; i print(); > return 0; >
Output: 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
Использование нового ключевого слова
В куче новый оператор обозначает запрос на выделение памяти. Если памяти достаточно, оператор new идентифицирует память и возвращает вновь выделенный и сконфигурированный адрес памяти в имя переменной.
Здесь переменная point является указателем информационного типа. Тип данных может быть любым типом встроенных данных вместе с массивом или любым типом пользовательских данных, таких как структура и класс.
Если мы добавим параметризованный конструктор, для нового ключевого слова потребуется непараметризованный конструктор для динамической инициализации. Поэтому мы собираемся использовать для этого фиктивный конструктор.
#include #define E 15 using namespace std; class Test < // private variables int m, n; public: // dummy constructor Test() <>// parameterized constructor Test(int m, int n) < this->m = m; this->n = n; > // function to print void print() < cout >; int main() < // allocating dynamic array // of Size N using new keyword Test* arr = new Test[E]; // calling constructor // for each index of array for (int j = 0; j < E; j++) < arr[j] = Test(j, j + 1); >// printing contents of array for (int j = 0; j < E; j++) < arr[j].print(); >return 0; >
Output: 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 11 12
Конструктор с аргументами по умолчанию
Определяя конструкторы с аргументами по умолчанию, это средство позволяет вызываемому конструктору указывать меньшее число аргументов вместо передачи всех аргументов, определенных в конструкторе. Если конструктор, вызываемый во время создания объекта, не указывает все аргументы, то пропущенные аргументы могут принимать значения по умолчанию, указанные в определении конструктора.
Однако, если конструктор объявлен внутри и определен вне класса, значения по умолчанию предоставляются в объявлении конструктора, а не в его определении.
Когда вызов конструктора указывает аргументы, соответствующие аргументам по умолчанию, прошлые аргументы всегда переопределяют значения по умолчанию.
Конструкторы с аргументами по умолчанию могут помочь уменьшить размер класса, поскольку нет необходимости создавать несколько конструкторов в классе. В этом можно убедиться, сравнив приведенную выше программу с предыдущей программой комплексного числа.
Однако в определенных ситуациях, если значение аргументов по умолчанию может измениться, лучше использовать перегруженный конструктор вместо одного конструктора с аргументами по умолчанию.
Список инициализаторов
C++ предоставляет альтернативный синтаксис для инициализации элементов данных объектов в конструкторе, известном как список инициализации. Конструктор прямоугольника с двумя параметрами можно переписать для использования списка инициализаторов следующим образом: прямоугольник(int a, int b): длина(a), дыхание(b)
Список инициализации помещается между списком параметров и открывающей фигурной скобкой тела конструктора. Список начинается с двоеточия(:) и разделяется запятыми.
Каждое предложение инициализации просто называет элементы данных, а в круглых скобках перечисляет значение, которое будет использоваться для инициализации члена данных.
Когда конструктор объявлен внутри и определен вне класса с использованием оператора разрешения области видимости, тогда список инициализации члена может быть указан только в определении конструктора, а не в его объявлении. Список инициализации позволяет инициализировать элементы данных во время их создания, что более эффективно, поскольку значения присваиваются еще до того, как конструктор начнет выполняться.
Динамическая инициализация с использованием конструктора
Члены данных объекта после создания могут быть инициализированы во время выполнения с помощью конструкторов. Такая инициализация элементов данных называется динамической инициализацией.
Основным преимуществом динамической инициализации является возможность разрешить различные режимы инициализации с использованием перегруженных конструкций. Следовательно, пользователь может предоставлять различные форматы данных в зависимости от требований.
Рассмотрим пример отображения роста человека в футах и дюймах.
Различные форматы для указания роста человека могут быть 5 футов, 5.5 футов и явно указывать, например, 5 футов и 8 дюймов.
#include #include Class height < Private: Int feet: Double inches; Public: Height(int f) < Feet=f; Inches=0.0; >Height(double f) < Feet=int(f); Inches=(f-int(f))*12.0; >Height() < Feet=inches=0; >Height(int f, double in) < Feet=f; inches=in; >Void show() < Cout>://end of class specification Int main() < Clrscr(); Height h1, h2, h3;// default constructor invoked Int ht_feet; Coutht_fract; H2= height(ht_fract); Int ft1; Double in1; Cout<>ft1>>in1; H3 = height(ft1, in1; H1.show(); h2.show(); h3.show(); Getch(); return 0; >
OUTPUT: Enter height in terms of feet only: 5 Enter height in terms of feet in the fractional form: 5.5 Enter height in terms of feet and inches: 5 8 Feet = 5 Inches = 0 Feet = 5 Inches = 6 Feet = 5 Inches = 8
Объяснение:
В этой программе у нас есть четыре конструктора. Аргументы параметризованным конструкторам предоставляются во время выполнения. Пользователь может указать рост человека в любом из следующих форматов:
- Без указания высоты и, следовательно, вызывается конструктор по умолчанию, который инициализирует футы и дюймы равными 0 каждый.
- Указание высоты только в футах в интегральной форме и для этого конструктора height(int); вызывается.
- Указание высоты только в футах в дробной форме и для этого конструктор высота (двойная); вызывается.
- Указание высоты в дюймах, конструктор высота (целое, двойное); вызывается.
Конструктор height() перегружен и какой из них будет вызван, зависит от аргументов, указанных конструктором.
На этом мы подошли к концу блога о конструкторе на C++. Мы надеемся, что вы смогли получить некоторые знания из того же. Если вы хотите узнать больше о таких понятиях, как конструктор в C++ или любом другом языке программирования, вы можете присоединиться Бесплатные онлайн-курсы Great Learning Academy прямо сейчас
- Платон Теги:
- Академия
- Byju-х
- C / C ++
- C ++
- Конструктор в C ++
- конструкторы в с++
- Coursera
- EdTech
- Развивающие игры
- Edutech
- LMS
- Мое большое обучение
- онлайн-образование
- Платон
- Платон блокчейн
- Платон Дай
- Платонный интеллект данных
- Платон Интеллектуальные данные
- Skillshare
- учебные пособия
- udemy