Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0495976_C19D7_shpory_s.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.82 Mб
Скачать
  1. Константные (const) и изменяемые (mutable) члены класса.

Другой вид непостоянной переменной, которая может быть изменена даже если она входит в константное выражение, объявляется с помощью модификатора mutable:

mutable <имя переменной>;

Назначение ключевого слова mutable состоит в спецификации членов данных некоторого класса, которые могут быть модифицированы константными функциями этого класса. Листинг 3.21 показывает пример, в котором член данных count модифицируется константной функцией F1.

class A {

public: mutable int count; int F1 (int p = 0) const // Объявление функции F1

count = p++ return count; //PI возвращает count

};

void main() {

A a;

cout “ a.Fl(3) “ end.1; // main выдает значение 4 )

Листинг 3.21. Изменение непостоянной переменной mutable.

Функцию-член со спецификацией const можно вызывать для постоянных объектов, а функцию-член без

такой спецификации - нельзя:

void f(X& mutable, const X& constant)

{

mutable.readme(); // нормально

mutable.writeme(7); // нормально

constant.readme(); // нормально

constant.writeme(7); // ошибка

}

Бьерн Страуструп. Язык программирования С++

126

В этом примере разумный транслятор смог бы обнаружить, что функция X::writeme() пытается изменить

постоянный объект. Однако, это непростая задача для транслятора. Из-за раздельной трансляции он в

общем случае не может гарантировать "постоянство" объекта, если нет соответствующего описания со

спецификацией const. Например, определения readme() и writeme() могли быть в другом файле:

class X {

int m;

public:

readme() const;

writeme(int i);

};

В таком случае описание readme() со спецификацией const существенно.

  1. Конструктор копирования для контейнерного класса.

Конструктор копирования предназначен для создания объектов данного класса путем копирования данных из другого, уже существующего объекта этого класса. Такие конструкторы особенно целесообразны для создания копий объектов, которые моделируют динамические структуры данных. Однако, по умолчанию компилятор создает так называемые конструкторы поверхностного копирования (shallow copy constructors), которые копируют только члены данных. Поэтому если какие-то члены данных содержат указатели, сами данные не будут копироваться. Для реализации "глубокого" копирования в код конструктора надо включить соответствующие инструкции.

Чтобы производные классы были не просто удобной формой краткого описания, в реализации языка

должен быть решен вопрос: к какому из производных классов относится объект, на который смотрит

указатель base*? Существует три основных способа ответа:

[1] Обеспечить, чтобы указатель мог ссылаться на объекты только одного типа ($$6.4.2);

[2] Поместить в базовый класс поле типа, которое смогут проверять функции;

[3] использовать виртуальные функции ($$6.2.5).

Указатели на базовые классы обыкновенно используются при проектировании контейнерных классов

(множество, вектор, список и т.д.). Тогда в случае [1] мы получим однородные списки, т.е. списки

объектов одного типа. Способы [2] и [3] позволяют создавать разнородные списки, т.е. списки объектов

нескольких различных типов (на самом деле, списки указателей на эти объекты). Способ [3] - это

специальный надежный в смысле типа вариант способа [2]. Особенно интересные и мощные варианты

дают комбинации способов [1] и [3]; они обсуждаются в главе 8.

Вначале обсудим простой способ с полем типа, т.е. способ [2]. Пример с классами manager/employee

можно переопределить так:

struct employee {

enum empl_type { M, E };

empl_type type;

employee* next;

char* name;

short department;

// ...

};

struct manager : employee {

employee* group;

short level;

// ...

};

Контейнерные классы -- это универсальные шаблонные классы, предназначенные для хранения элементов заданного типа в смежных областях памяти. Стандарт C++ уже включает в себя большое количество контейнеров, как часть STL (Standard Template Library -- Стандартная Библиотека Шаблонов).

Qt имеет свой набор шаблонных классов. Таким образом, при создании программ разработчик может использовать как контейнерные классы из библиотеки Qt, так и классы из STL

Вектор – это контейнерный класс, в котором доступ к его элементам осуществляется по индексу. В силу этого векторы во многом напоминают одномерные массивы. Библиотека STL предоставляет вам контейнерный класс vector, определенный в заголовочном файле и доступный в пространстве имен std. Класс vector ведет себя подобно массиву, однако предоставляет больше возможностей по управлению ним. В частности, вектор можно наращивать по мере небходимости, и он обеспечивает контроль значений индексов. Определение класса vector выглядит следующим образом:

template >

class vector

{

// члены класса

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]