Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

Объекты класса создаются снизу вверх, начиная с объектов базового класса (см. раздел 14.3.1) в порядке их объявления. Затем в порядке объявления создаются члены класса, после чего следует код самого конструктора. Если программист не сделает чего-нибудь очень странного, это гарантирует, что каждый объект класса будет создан до своего использования.

Если конструктор с одним аргументом не объявлен с помощью ключевого слова explicit, то он определяет неявное преобразование типа своего аргумента в свой класс.

class Date {

public:

  Date(string);

  explicit Date(long); // используется целочисленное

                       // представление даты

  // ...

};

void f(Date);

Date d1 = "June 5, 1848"; // OK

f("June 5, 1848");        // OK

Date d2 = 2007*12*31+6*31+5; // ошибка: Date(long) — явный

                             // конструктор

f(2007*12*31+6*31+5);        // ошибка: Date(long) — явный конструктор

Date d3(2007*12*31+6*31+5);        // OK

Date d4 = Date(2007*12*31+6*31+5); // OK

f(Date(2007*12*31+6*31+5));        // OK

Если базовые классы или члены производного класса не требуют явных аргументов и в классе нет других конструкторов, то автоматически генерируется конструктор по умолчанию (default constructor). Этот конструктор инициализирует каждый объект базового класса и каждый член, имеющий конструктор по умолчанию (оставляя члены, не имеющие конструкторы по умолчанию, неинициализированными). Рассмотрим пример.

struct S {

  string name, address;

  int x;

};

Этот класс S имеет неявный конструктор S, инициализирующий члены name и address, но не x

<p id="AutBody_Root618"><strong>A.12.3.1. Деструкторы</strong></p>

Смысл операции удаления объекта (т.е. что произойдет, когда объект выйдет за пределы области видимости) можно определить с помощью деструктора (destructor). Имя деструктора состоит из символа ~ (оператор дополнения), за которым следует имя класса.

class Vector { // вектор чисел типа double

public:

  explicit Vector(int s):sz(s),p(new double[s]) { }

  // конструктор

  ~Vector { delete[] p; }

  // деструктор

  // ...

private:

  int sz;

  double* p;

};

void f(int ss)

{

  Vector v(s);

  // ...

} // при выходе из функции f объект v будет уничтожен;

  // для этого будет вызван деструктор класса Vector

Деструкторы, вызывающие деструкторы членов класса, могут генерироваться компилятором. Если класс используется как базовый, он обычно должен иметь виртуальный деструктор (см. раздел 17.5.2).

Деструкторы, как правило, используются для “очистки” и освобождения ресурсов. Объекты класса уничтожаются сверху вниз, начиная с кода самого деструктора, за которым следуют члены в порядке их объявления, а затем — объекты базового класса в порядке их объявления, т.е. в порядке, обратном их созданию (см. раздел A.12.3.1).

<p id="AutBody_Root619"><strong>A.12.3.2. Копирование</strong></p>

Можно определить суть копирования объекта класса.

class Vector { // вектор чисел типа double

public:

  explicit Vector(int s):sz(s), p(new double[s]) { }

  // конструктор

  ~Vector { delete[] p; }         // деструктор

  Vector(const Vector&);            // копирующий конструктор

  Vector& operator=(const Vector&); // копирующее присваивание

  // ...

private:

  int sz;

  double* p;

};

void f(int ss)

{

  Vector v(s);

  Vector v2 = v; // используем копирующий конструктор

  // ...

  v = v2;        // используем копирующее присваивание

  // ...

}

По умолчанию (т.е. если вы не определили копирующий конструктор и копирующее присваивание) компилятор сам генерирует копирующие операции. По умолчанию копирование производится почленно (см. также разделы 14.2.4 и 18.2). 

<p id="AutBody_Root620"><strong>A.12.4. Производные классы</strong></p>

Класс можно определить производным от других классов. В этом случае он наследует члены классов, от которых происходит (своих базовых классов).

struct B {

  int mb;

  void fb { };

};

class D:B {

  int md;

  void fd;

};

Перейти на страницу:

Похожие книги

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT