ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4300
Скачиваний: 28
Часть II. Язык программирования С++
196
public:
int count() { return n.count(); }
};
int main()
{
Outer::Inner m;
cout << m.count() << endl; // печатает 1
return 0;
}
14.13. Локальные классы
Класс, определенный внутри тела функции, называется
локаль-
ным
. Такой класс виден только в теле функции. Функции-члены
локального класса должны определяться внутри самого класса.
В листинге 14.15 приведен пример определения локального класса.
Листинг 14.15. Определение локального класса
#include <iostream>
using namespace std;
int inc(int n)
{
struct Inc
{
int inc(int n) { return ++n; }
};
Inc i;
return i.inc(n);
}
int main()
{
cout << inc(10) << endl; // печатает 11
return 0;
}
Г Л А В А
15
Конструкторы
и деструкторы
15.1. Конструктор класса
Конструктором
называется функция-член класса, имя которой
совпадает с именем этого класса. Вызов конструктора указывает
компилятору, что создается новый объект класса. Вызов конст-
руктора может выполняться как явно, так и неявно. При опреде-
лении объекта вызов конструктора происходит неявно. В конст-
рукторе можно использовать данные и функции-члены класса, а
также указатель
this
. Тело конструктора используется для ини-
циализации данных-членов класса. Конструкторы должны удов-
летворять следующим требованиям:
конструктор не имеет типа возвращаемого значения и, следо-
вательно, не должен возвращать значения;
конструктор не может быть объявлен с квалификаторами
const
или
volatile
;
конструктор не может быть объявлен со спецификатором
static
;
конструктор не может быть объявлен со спецификатором
virtual
.
Из первого требования следует, что для обработки ошибок в кон-
структоре должны использоваться исключения. Хотя следует за-
метить, что возвращать значения из конструктора можно через
параметры-ссылки.
Часть II. Язык программирования С++
198
Кроме того, отметим, что классы, содержащие конструкторы, не
могут быть членами объединений.
15.2. Список инициализации
Если членом класса является константа, ссылка или объект дру-
гого класса, то инициализация такого члена класса невозможна в
теле конструктора. В этих случаях используется список инициа-
лизации данных-членов класса, который записывается после спи-
ска параметров конструктора и отделяется от него символом
:
.
Список инициализации должен содержать вызовы конструкторов
инициализируемых объектов. В списке инициализации также мо-
гут инициализироваться и другие данные-члены класса.
В листинге 15.1 приведен пример инициализации данных-членов
класса, используя список инициализации.
Листинг 15.1. Использование списка инициализации
#include <iostream>
using namespace std;
class Demo
{
const int a;
int b, c;
public:
Demo(int _b, int _c): a(0), b(_b) { c = _c; }
int getSum() { return a + b + c; }
};
int main()
{
Demo d(1, 2);
cout << d.getSum() << endl; // печатает 3
return 0;
}
В принципе программа работает быстрее, если данные-члены
класса инициализируются в списке инициализации, а не в теле
Глава 15. Конструкторы и деструкторы
199
конструктора. Так как в последнем случае перед передачей
управления телу конструктора для каждого атрибута класса вы-
зывается конструктор по умолчанию этого атрибута.
В заключение этого раздела заметим, что конструкторы данных-
членов класса вызываются в порядке объявления этих данных
в классе, а не в порядке их появления в списке инициализации.
15.3. Конструктор по умолчанию
Конструктором по умолчанию
называется конструктор, который
можно вызвать без аргументов. Конструктор по умолчанию мож-
но определить двумя способами:
без параметров;
со списком параметров, в котором все параметры имеют зна-
чения по умолчанию.
Класс может иметь только один конструктор по умолчанию. Если
класс совсем не имеет конструкторов и не содержит ссылок и
констант в качестве членов класса, то конструктор по умолчанию
генерируется компилятором. Этот конструктор имеет следующий
прототип:
public: inline имя_класса();
Такой конструктор вызывает сначала конструкторы по умолча-
нию базовых классов, а затем конструкторы по умолчанию для
данных-членов класса.
В листинге 15.2 приведен пример вызова конструкторов по умол-
чанию.
Листинг 15.2. Вызов конструкторов по умолчанию
#include <iostream>
using namespace std;
struct A
{
int a;
A(int _a = 20): a(_a) { cout << "a = " << a << endl; }
};
Часть II. Язык программирования С++
200
struct B
{
int b;
B(int _b = 10): b(_b) { cout << "b = " << b << endl; }
};
struct C: public B // С наследуется от B
{
A a; // С содержит A
};
int main()
{
C c; // печатает: b = 10, a = 20
return 0;
}
Если класс имеет хотя бы один конструктор, то конструктор по
умолчанию не генерируется компилятором и его должен опреде-
лить разработчик класса.
Чтобы запретить использование конструктора по умолчанию, его
нужно поместить в
private
раздел класса. Это предотвращает
возможность создания неинициализированных объектов.
15.4. Конструктор копирования
Конструктором копирования
называется конструктор, первый
параметр которого является ссылкой на объект класса, которому
принадлежит конструктор, а остальные параметры либо отсутст-
вуют, либо имеют значения, заданные по умолчанию. Конструк-
тор копирования используется компилятором для инициализации
объекта другим объектом этого же класса. Если конструктор ко-
пирования не определен, то компилятор сам генерирует конст-
руктор копирования по умолчанию, который имеет следующий
прототип:
public: inline имя_класса(const имя_класса&);
Выполняет копирование данных из объекта аргумента конструк-
тора в конструируемый объект.