Правила для пропуска значений параметров

Если программа опускает определенный параметр для функции, обеспечивающей значения по умолчанию, то следует опустить и все последующие параметры. Другими словами, вы не можете опускать средний параметр. В случае предыдущей программы, если требовалось опустить значение параметра b в show_parameters, программа также должна была опустить значение параметра с. Вы не можете указать значение для а и с, опуская значение Ь.

Задание значений по умолчанию

Когда вы определяете функцию, C++ позволяет вам указать значения по умолчанию для одного или нескольких параметров. Если программа в дальнейших вызовах этой функции опускает один или несколько параметров, то функция будет использовать для них значения по умолчанию. Чтобы присвоить параметру значение по умолчанию, просто используйте оператор присваивания внутри определения функции.
Например, следующая функция payroll указывает значения по умолчанию для параметров hours и rate:

float payroll(int employ_id, float hours = 40, float rate = 5.50)

{

// операторы
}

Когда программа опускает один параметр, она должна опускать все последующие параметры.

 

Билет 16. Классы. Инкапсуляция.

Инкапсуляция (encapsulation) - это механизм, который объединяет данные и код, манипулирующий зтими данными, а также защищает и то, и другое от внешнего вмешательства или неправильного использования. В объектно-ориентированном программировании код и данные могут быть объединены вместе; в этом случае говорят, что создаётся так называемый "чёрный ящик". Когда коды и данные объединяются таким способом, создаётся объект (object). Другими словами, объект - это то, что поддерживает инкапсуляцию.

Внутри объекта коды и данные могут быть закрытыми (private). Закрытые коды или данные доступны только для других частей этого объекта. Таким образом, закрытые коды и данные недоступны для тех частей программы, которые существуют вне объекта. Если коды и данные являются открытыми, то, несмотря на то, что они заданы внутри объекта, они доступны и для других частей программы. Характерной является ситуация, когда открытая часть объекта используется для того, чтобы обеспечить контролируемый интерфейс закрытых элементов объекта.

На самом деле объект является переменной определённого пользователем типа. Может показаться странным, что объект, который объединяет коды и данные, можно рассматривать как переменную. Однако применительно к объектно-ориентированному программированию это именно так. Каждый элемент данных такого типа является составной переменной.

 

Класс - это пользовательский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования.

Посмотрим, как можно представить в языке понятие даты, используя для этого тип структуры и набор

функций, работающих с переменными этого типа:

struct date { int month, day, year; };

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(const date*);

//...

Никакой явной связи между функциями и структурой date нет. Ее можно установить, если описать

функции как члены структуры:

struct date {

int month, day, year;

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();};

Описанные таким образом функции называются функциями-членами.

Класс – это сложная структура данных, определяемая пользователем. В языке С++ под классом понимают производный тип данных, объединенный с множеством функций и операций, работающих с объектами этого типа, и сформированный при помощи описателей class, struct или union. Синтаксис определения класса представляется так:

<описатель> имя_класса [: базовый список] {<список элементов>}

В этом определении <описатель> - это один из описателей class, struct или union Имя_класса – идентификатор из латинских букв и цифр, начинающихся с буквы. В базовом списке перечисляются базовый класс или классы, свойства которых исследуются, а <список элементов> объявляет элементы класса – элементы данных и функции (методы класса). Самым простейшим примером описания класса может служить объявление класса с описателем struct, например:

struct SLine //Класс прямая

{

int XFirst, YFirst; //Начальные и конечные

int XLast, YLast; //Координаты отрезка прямой

COLORREF LineColor; //Цвет прямой

//Инкапсуляция функции в класс

DrawLine(CDC *pDC, int X, int Y); // Отрисовка отрезка начиная

// с координат X,Y.

}

В примере объявлен класс отрезка прямой SLine. Класс содержит основные элементы данных для отрезка прямой и функцию отображения этой прямой на экране.

Для определения объектов класса SLine можно воспользоваться идентификатором SLine как описателем типа:

SLine Line1, Line2,Line3;

В результате такого описания программа отведет три области памяти по структуре и размеру соответствующие элементам класса SLine.

Объект - это абстрактная сущность, наделенная характеристиками объектов окружающего нас реального мира. Создание объектов и манипулирование ими - это вовсе не привилегия языка C++, а скорее результат методологии программирования, воплощающей в кодовых конструкциях описания объектов и операции над ними. Каждый объект программы, как и любой реальный объект, отличается собственными атрибутами и характерным поведением. Объекты можно классифицировать по разным категориям\

Класс - это пользоваельский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования

Каждое объявление внутри класса определяет привилегию доступа к именам класса в зависимости от того, в какой секции имя появляется. Каждая секция начинается с одного из ключевых слов: private, protected и public

class className

private:

<приватные члены данных> <приватные конструкторы> <приватные методы>

protected:

<защищенные члены данных> <защищенные конструкторы> <защищенные методы>

public:

<общедоступные свойства> <общедоступные члены данных> “збщедоступные конструкторы> <общедоступный деструктор> общедоступные методы>

Таким образом, объявление базового класса на C++ предоставляет следующие права доступа и соответствующие области видимости:

• Приватные private имена имеют наиболее ограниченный доступ, разрешенный только методам данного класса. Доступ производных классов к приватным методам базовых классов запрещен.

• Защищенные protected имена имеют доступ, разрешенный методам данного и производных от него классов.

• Общедоступные public имена имеют неограниченный доступ, разрешенный методам всех классов и их объектов.

Следующие правила применяются при образовании различных секций объявления класса:

1. Секции могут появляться в любом порядке, а их названия могут встречаться повторно.

2. Если секция не названа, компилятор считает последующие объявления имен класса приватными. Здесь проявляется отличие объявлений класса и структуры - последняя рассматривается по умолчанию как общедоступная.

3. По мере возможности не помещайте члены данных в общедоступную секцию, если только вы действительно не хотите разрешить доступ к ним отовсюду. Обычно их объявляют защищенными, чтобы разрешить доступ только методам производных классов.

4. Используйте методы для выборки, проверки и установки значений свойств и членов данных.

5. Конструкторы и деструкторы являются специальными функциями, которые не возвращают значения и имеют имя своего класса. Конструктор строит объект данного класса, а деструктор его удаляет.

6. Методы (так же как конструкторы и деструкторы), которые содержат более одной инструкции C++, рекомендуется объявлять вне класса.

 

Билет 17. Классы. Наследование.

Наследование (inheritance) - это процесс, посредством которого один объект может приобретать свойства другого. Точнее, объект может наследовать основные свойства другого объекта и добавлять к ним черты, характерные только для него. Наследование является важным, поскольку оно позволяет поддерживать концепцию иерархии классов (hierarchical classification). Применение иерархии классов делает управляемыми большие потоки информации. Например, подумайте об описании жилого дома. Дом - это часть общего класса, называемого строением. С другой стороны, строение - это часть более общего класса - конструкции, который является частью ещё более общего класса объектов, который можно назвать созданием рук человека. В каждом случае порождённый класс наследует все, связанные с родителем, качества и добавляет к ним свои собственные определяющие характеристики. Без использования иерархии классов, для каждого объекта пришлось бы задать все характеристики, которые бы исчерпывающи его определяли. Однако при использовании наследования можно описать объект путём определения того общего класса (или классов), к которому он относится, с теми специальными чертами, которые делают объект уникальным. Наследование играет очень важную роль в OOP.

 

 

Класс - это пользовательский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования.

Посмотрим, как можно представить в языке понятие даты, используя для этого тип структуры и набор

функций, работающих с переменными этого типа:

struct date { int month, day, year; };

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(const date*);

//...

Никакой явной связи между функциями и структурой date нет. Ее можно установить, если описать

функции как члены структуры:

struct date {

int month, day, year;

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();};

Описанные таким образом функции называются функциями-членами.

Класс – это сложная структура данных, определяемая пользователем. В языке С++ под классом понимают производный тип данных, объединенный с множеством функций и операций, работающих с объектами этого типа, и сформированный при помощи описателей class, struct или union. Синтаксис определения класса представляется так:

<описатель> имя_класса [: базовый список] {<список элементов>}

В этом определении <описатель> - это один из описателей class, struct или union Имя_класса – идентификатор из латинских букв и цифр, начинающихся с буквы. В базовом списке перечисляются базовый класс или классы, свойства которых исследуются, а <список элементов> объявляет элементы класса – элементы данных и функции (методы класса). Самым простейшим примером описания класса может служить объявление класса с описателем struct, например:

struct SLine //Класс прямая

{

int XFirst, YFirst; //Начальные и конечные

int XLast, YLast; //Координаты отрезка прямой

COLORREF LineColor; //Цвет прямой

//Инкапсуляция функции в класс

DrawLine(CDC *pDC, int X, int Y); // Отрисовка отрезка начиная

// с координат X,Y.

}

В примере объявлен класс отрезка прямой SLine. Класс содержит основные элементы данных для отрезка прямой и функцию отображения этой прямой на экране.

Для определения объектов класса SLine можно воспользоваться идентификатором SLine как описателем типа:

SLine Line1, Line2,Line3;

В результате такого описания программа отведет три области памяти по структуре и размеру соответствующие элементам класса SLine.

Объект - это абстрактная сущность, наделенная характеристиками объектов окружающего нас реального мира. Создание объектов и манипулирование ими - это вовсе не привилегия языка C++, а скорее результат методологии программирования, воплощающей в кодовых конструкциях описания объектов и операции над ними. Каждый объект программы, как и любой реальный объект, отличается собственными атрибутами и характерным поведением. Объекты можно классифицировать по разным категориям\

Класс - это пользоваельский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования

Каждое объявление внутри класса определяет привилегию доступа к именам класса в зависимости от того, в какой секции имя появляется. Каждая секция начинается с одного из ключевых слов: private, protected и public

class className

private:

<приватные члены данных> <приватные конструкторы> <приватные методы>

protected:

<защищенные члены данных> <защищенные конструкторы> <защищенные методы>

public:

<общедоступные свойства> <общедоступные члены данных> “збщедоступные конструкторы> <общедоступный деструктор> общедоступные методы>

Таким образом, объявление базового класса на C++ предоставляет следующие права доступа и соответствующие области видимости:

• Приватные private имена имеют наиболее ограниченный доступ, разрешенный только методам данного класса. Доступ производных классов к приватным методам базовых классов запрещен.

• Защищенные protected имена имеют доступ, разрешенный методам данного и производных от него классов.

• Общедоступные public имена имеют неограниченный доступ, разрешенный методам всех классов и их объектов.

Следующие правила применяются при образовании различных секций объявления класса:

1. Секции могут появляться в любом порядке, а их названия могут встречаться повторно.

2. Если секция не названа, компилятор считает последующие объявления имен класса приватными. Здесь проявляется отличие объявлений класса и структуры - последняя рассматривается по умолчанию как общедоступная.

3. По мере возможности не помещайте члены данных в общедоступную секцию, если только вы действительно не хотите разрешить доступ к ним отовсюду. Обычно их объявляют защищенными, чтобы разрешить доступ только методам производных классов.

4. Используйте методы для выборки, проверки и установки значений свойств и членов данных.

5. Конструкторы и деструкторы являются специальными функциями, которые не возвращают значения и имеют имя своего класса. Конструктор строит объект данного класса, а деструктор его удаляет.

6. Методы (так же как конструкторы и деструкторы), которые содержат более одной инструкции C++, рекомендуется объявлять вне класса.

 

Билет 18. Классы. Полиморфизм.

Полиморфизм (polymorphism) (от греческого polymorphos) - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, применительно к объектно-ориентированному программированию, является использование одного имени для задания общих для класса действий. Выполнение каждого конкретного действия будет определяться типом данных. Например для языка Си, в котором полиморфизм поддерживается недостаточно, нахождение абсолютной величины числа требует трёх различных функций: abs(), labs() и fabs(). Эти функции подсчитывают и возвращают абсолютную величину целых, длинных целых и чисел с плавающей точкой соответственно. В С++ каждая из этих функций может быть названа abs(). Тип данных, который используется при вызове функции, определяет, какая конкретная версия функции действительно выполняется. В С++ можно использовать одно имя функции для множества различных действий. Это называется перегрузкой функций (function overloading).

В более общем смысле, концепцией полиморфизма является идея "один интерфейс, множество методов". Это означает, что можно создать общий интерфейс для группы близких по смыслу действий. Преимуществом полиморфизма является то, что он помогает мнижать сложность программ, разрешая использование того же интерфейса для задания единого класса действий. Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор. Вам, как программисту, не нужно делать этот выбор самому. Нужно только помнить и использовать общий интерфейс. Пример из предыдущего абзаца показывает, как, имея три имени для функции определения абсолютной величины числа вместо одного, обычная задача становится более сложной, чем это действительно необходимо.

Полиморфизм может применяться также и к операторам. Фактически во всех языках программирования ограниченно применяется полиморфизм, например, в арифметических операторах. Так, в Си, символ + используется для складывания целых, длинных целых, символьных переменных и чисел с плавающей точкой. В этом случае компилятор автоматически определяет, какой тип арифметики требуется. В С++ вы можете применить эту концепцию и к другим, заданным вами, типам данных. Такой тип полиморфизма называется перегрузкой операторов (operator overloading).

Ключевым в понимании полиморфизма является то, что он позволяет вам манипулировать объектами различной степени сложности путём создания общего для них стандартного интерфейса для реализации похожих действий.

 

Класс - это пользовательский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования.

Посмотрим, как можно представить в языке понятие даты, используя для этого тип структуры и набор

функций, работающих с переменными этого типа:

struct date { int month, day, year; };

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(const date*);

//...

Никакой явной связи между функциями и структурой date нет. Ее можно установить, если описать

функции как члены структуры:

struct date {

int month, day, year;

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();};

Описанные таким образом функции называются функциями-членами.

Класс – это сложная структура данных, определяемая пользователем. В языке С++ под классом понимают производный тип данных, объединенный с множеством функций и операций, работающих с объектами этого типа, и сформированный при помощи описателей class, struct или union. Синтаксис определения класса представляется так:

<описатель> имя_класса [: базовый список] {<список элементов>}

В этом определении <описатель> - это один из описателей class, struct или union Имя_класса – идентификатор из латинских букв и цифр, начинающихся с буквы. В базовом списке перечисляются базовый класс или классы, свойства которых исследуются, а <список элементов> объявляет элементы класса – элементы данных и функции (методы класса). Самым простейшим примером описания класса может служить объявление класса с описателем struct, например:

struct SLine //Класс прямая

{

int XFirst, YFirst; //Начальные и конечные

int XLast, YLast; //Координаты отрезка прямой

COLORREF LineColor; //Цвет прямой

//Инкапсуляция функции в класс

DrawLine(CDC *pDC, int X, int Y); // Отрисовка отрезка начиная

// с координат X,Y.

}

В примере объявлен класс отрезка прямой SLine. Класс содержит основные элементы данных для отрезка прямой и функцию отображения этой прямой на экране.

Для определения объектов класса SLine можно воспользоваться идентификатором SLine как описателем типа:

SLine Line1, Line2,Line3;

В результате такого описания программа отведет три области памяти по структуре и размеру соответствующие элементам класса SLine.

Объект - это абстрактная сущность, наделенная характеристиками объектов окружающего нас реального мира. Создание объектов и манипулирование ими - это вовсе не привилегия языка C++, а скорее результат методологии программирования, воплощающей в кодовых конструкциях описания объектов и операции над ними. Каждый объект программы, как и любой реальный объект, отличается собственными атрибутами и характерным поведением. Объекты можно классифицировать по разным категориям\

Класс - это пользоваельский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования

Каждое объявление внутри класса определяет привилегию доступа к именам класса в зависимости от того, в какой секции имя появляется. Каждая секция начинается с одного из ключевых слов: private, protected и public

class className

private:

<приватные члены данных> <приватные конструкторы> <приватные методы>

protected:

<защищенные члены данных> <защищенные конструкторы> <защищенные методы>

public:

<общедоступные свойства> <общедоступные члены данных> “збщедоступные конструкторы> <общедоступный деструктор> общедоступные методы>

Таким образом, объявление базового класса на C++ предоставляет следующие права доступа и соответствующие области видимости:

• Приватные private имена имеют наиболее ограниченный доступ, разрешенный только методам данного класса. Доступ производных классов к приватным методам базовых классов запрещен.

• Защищенные protected имена имеют доступ, разрешенный методам данного и производных от него классов.

• Общедоступные public имена имеют неограниченный доступ, разрешенный методам всех классов и их объектов.

Следующие правила применяются при образовании различных секций объявления класса:

1. Секции могут появляться в любом порядке, а их названия могут встречаться повторно.

2. Если секция не названа, компилятор считает последующие объявления имен класса приватными. Здесь проявляется отличие объявлений класса и структуры - последняя рассматривается по умолчанию как общедоступная.

3. По мере возможности не помещайте члены данных в общедоступную секцию, если только вы действительно не хотите разрешить доступ к ним отовсюду. Обычно их объявляют защищенными, чтобы разрешить доступ только методам производных классов.

4. Используйте методы для выборки, проверки и установки значений свойств и членов данных.

5. Конструкторы и деструкторы являются специальными функциями, которые не возвращают значения и имеют имя своего класса. Конструктор строит объект данного класса, а деструктор его удаляет.

6. Методы (так же как конструкторы и деструкторы), которые содержат более одной инструкции C++, рекомендуется объявлять вне класса.

 

Билет 19. Классы. Чистые виртуальные функции.

Виртуальный метод (виртуальная функция) — в объектно-ориентированном программировании метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения. Таким образом, программисту необязательно знать точный тип объекта для работы с ним через виртуальные методы: достаточно лишь знать, что объект принадлежит классу или наследнику класса, в котором метод объявлен.

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

Базовый класс может и не предоставлять реализации виртуального метода, а только декларировать его существование. Такие методы без реализации называются «чисто виртуальными» (калька с англ. pure virtual) или абстрактными. Класс, содержащий хотя бы один такой метод, тоже будет абстрактным. Объект такого класса создать нельзя (в некоторых языках допускается, но вызов абстрактного метода приведёт к ошибке). Наследники абстрактного класса должны предоставить реализацию для всех его абстрактных методов, иначе они, в свою очередь, будут абстрактными классами.

Для каждого класса, имеющего хотя бы один виртуальный метод, создаётся таблица виртуальных методов. Каждый объект хранит указатель на таблицу своего класса. Для вызова виртуального метода используется такой механизм: из объекта берётся указатель на соответствующую таблицу виртуальных методов, а из неё, по фиксированному смещению, — указатель на реализацию метода, используемого для данного класса. При использовании множественного наследования или интерфейсов ситуация несколько усложняется за счёт того, что таблица виртуальных методов становится нелинейной.

Очередная модификация базового класса приводит к неожиданным последствиям. Эта модификация состоит в изменении спецификатора функции-члена базового класса. Мы (впервые!) используем спецификатор virtual в объявлении функции. Функции, объявленные со спецификатором virtual, называются виртуальными функциями. Введение виртуальных функций в объявление базового класса (всего лишь один спецификатор) имеет столь значительные последствия для методологии объектно-ориентированного программирования, что мы лишний раз приведём модифицированное объявление класса A:

class A
{
 public:
 virtual int Fun1(int);
};

Один дополнительный спецификатор в объявлении функции и больше никаких (пока никаких) изменений в объявлениях производных классов. Как всегда, очень простая функция main(). В ней мы определяем указатель на объект базового класса, настраиваем его на объект производного типа, после чего по указателю мы вызываем функцию Fun1():

void main ()
{
 A *pObj;
 A MyA;
 AB MyAB;
 pObj = &MyA;
 pObj->Fun1(1);
 AC MyAC;
 pObj = &MyAC;
 pObj->Fun1(1);
}

Если бы не спецификатор virtual, результат выполнения выражения вызова

pObj->Fun1(1);

был бы очевиден: как известно, выбор функции определяется типом указателя.

Однако спецификатор virtual меняет всё дело. Теперь выбор функции определяется типом объекта, на который настраивается указатель базового класса. Если в производном классе объявляется нестатическая функция, у которой имя, тип возвращаемого значения и список параметров совпадают с аналогичными характеристиками виртуальной функции базового класса, то в результате выполнения выражения вызова вызывается функция-член производного класса.

Сразу надо заметить, что возможность вызова функции-члена производного класса по указателю на базовый класс не означает, что появилась возможность наблюдения за объектом "сверху вниз" из указателя на объект базового класса. Невиртуальные функции-члены и данные по-прежнему недоступны. И в этом можно очень легко убедиться. Для этого достаточно попробовать сделать то, что мы уже однажды проделали - вызвать неизвестную в базовом классе функцию-член производного класса:

//pObj->Fun2(2);
//pObj->AC::Fun1(2);

Результат отрицательный. Указатель, как и раньше, настроен лишь на базовый фрагмент объекта производного класса. И всё же вызов функций производного класса возможен. Когда-то, в разделах, посвящённых описанию конструкторов, нами был рассмотрен перечень регламентных действий, которые выполняются конструктором в ходе преобразования выделенного фрагмента памяти в объект класса. Среди этих мероприятий упоминалась инициализация таблиц виртуальных функций.

Наличие этих самых таблиц виртуальных функций можно попытаться обнаружить с помощью операции sizeof. Конечно, здесь всё зависит от конкретной реализации, но, по крайней мере, в версии Borland C++ объект-представитель класса, содержащего объявления виртуальных функций, занимает больше памяти, нежели объект аналогичного класса, в котором те же самые функции объявлены без спецификатора virtual.

cout << "Размеры объекта: " << sizeof(MyAC) << "…" << endl;

Так что объект производного класса приобретает дополнительный элемент - указатель на таблицу виртуальных функций. Схему такого объекта можно представить следующим образом (указатель на таблицу мы обозначим идентификатором vptr, таблицу виртуальных функций - идентификатором vtbl):

MyAC::=vptr
A
AC
vtbl::=&AC::Fun1

На нашей новой схеме объекта указатель на таблицу (массив из одного элемента) виртуальных функций не случайно отделён от фрагмента объекта, представляющего базовый класс лишь пунктирной линией. Он находится в поле зрения этого фрагмента объекта. Благодаря доступности этого указателя оператор вызова виртуальной функции Fun1

pObj->Fun1(1);

можно представить следующим образом:

(*(pObj->vptr[0])) (pObj,1);

Очень часто в программах не требуется создавать объекты базовых классов. Т.е. базовые классы нужны только для того, чтобы построить иерархию классов и определить общие свойства для производных классов. Такие классы можно сделать абстрактными (abstract class). При попытке создания объекта абстрактного класса, компилятор выдаст ошибку.

Чтобы сделать класс абстрактным, нужно объявить одну из виртуальных функций чистой.

Чистая виртуальная функция (pure virtual function) как бы намекает, что она будет реализована в производных классах.

Чтобы сделать виртуальную функцию чистой (pure), нужно добавить после заголовка функции символы =0 (знак равенства и ноль):

class Base{public: virtual void method () =0; virtual ~Base() =0;};

В данном случае уже не нужно писать определение такой функции. Помимо этого теперь нельзя создавать объекты класса Base, так как он стал абстрактным.

Символы =0 необязательно добавлять ко всем виртуальным функциям, достаточно добавить к одной.

 

Класс - это пользовательский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования.

Посмотрим, как можно представить в языке понятие даты, используя для этого тип структуры и набор

функций, работающих с переменными этого типа:

struct date { int month, day, year; };

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(const date*);

//...

Никакой явной связи между функциями и структурой date нет. Ее можно установить, если описать

функции как члены структуры:

struct date {

int month, day, year;

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();};

Описанные таким образом функции называются функциями-членами.

Класс – это сложная структура данных, определяемая пользователем. В языке С++ под классом понимают производный тип данных, объединенный с множеством функций и операций, работающих с объектами этого типа, и сформированный при помощи описателей class, struct или union. Синтаксис определения класса представляется так:

<описатель> имя_класса [: базовый список] {<список элементов>}

В этом определении <описатель> - это один из описателей class, struct или union Имя_класса – идентификатор из латинских букв и цифр, начинающихся с буквы. В базовом списке перечисляются базовый класс или классы, свойства которых исследуются, а <список элементов> объявляет элементы класса – элементы данных и функции (методы класса). Самым простейшим примером описания класса может служить объявление класса с описателем struct, например:

struct SLine //Класс прямая

{

int XFirst, YFirst; //Начальные и конечные

int XLast, YLast; //Координаты отрезка прямой

COLORREF LineColor; //Цвет прямой

//Инкапсуляция функции в класс

DrawLine(CDC *pDC, int X, int Y); // Отрисовка отрезка начиная

// с координат X,Y.

}

В примере объявлен класс отрезка прямой SLine. Класс содержит основные элементы данных для отрезка прямой и функцию отображения этой прямой на экране.

Для определения объектов класса SLine можно воспользоваться идентификатором SLine как описателем типа:

SLine Line1, Line2,Line3;

В результате такого описания программа отведет три области памяти по структуре и размеру соответствующие элементам класса SLine.

Объект - это абстрактная сущность, наделенная характеристиками объектов окружающего нас реального мира. Создание объектов и манипулирование ими - это вовсе не привилегия языка C++, а скорее результат методологии программирования, воплощающей в кодовых конструкциях описания объектов и операции над ними. Каждый объект программы, как и любой реальный объект, отличается собственными атрибутами и характерным поведением. Объекты можно классифицировать по разным категориям\

Класс - это пользоваельский тип. Этот раздел знакомит с основными средствами определения класса,

создания его объектов, работы с такими объектами и, наконец, удаления этих объектов после

использования

Каждое объявление внутри класса определяет привилегию доступа к именам класса в зависимости от того, в какой секции имя появляется. Каждая секция начинается с одного из ключевых слов: private, protected и public

class className

private:

<приватные члены данных> <приватные конструкторы> <приватные методы>

protected:

<защищенные члены данных> <защищенные конструкторы> <защищенные методы>

public:

<общедоступные свойства> <общедоступные члены данных> “збщедоступные конструкторы> <общедоступный деструктор> общедоступные методы>

Таким образом, объявление базового класса на C++ предоставляет следующие права доступа и соответствующие области видимости:

• Приватные private имена имеют наиболее ограниченный доступ, разрешенный только методам данного класса. Доступ производных классов к приватным методам базовых классов запрещен.

• Защищенные protected имена имеют доступ, разрешенный методам данного и производных от него классов.

• Общедоступные public имена имеют неограниченный доступ, разрешенный методам всех классов и их объектов.

Следующие правила применяются при образовании различных секций объявления класса:

1. Секции могут появляться в любом порядке, а их названия могут встречаться повторно.

2. Если секция не названа, компилятор считает последующие объявления имен класса приватными. Здесь проявляется отличие объявлений класса и структуры - последняя рассматривается по умолчанию как общедоступная.

3. По мере возможности не помещайте члены данных в общедоступную секцию, если только вы действительно не хотите разрешить доступ к ним отовсюду. Обычно их объявляют защищенными, чтобы разрешить доступ только методам производных классов.

4. Используйте методы для выборки, проверки и установки значений свойств и членов данных.

5. Конструкторы и деструкторы являются специальными функциями, которые не возвращают значения и имеют имя своего класса. Конструктор строит объект данного класса, а деструктор его удаляет.

6. Методы (так же как конструкторы и деструкторы), которые содержат более одной инструкции C++, рекомендуется объявлять вне класса.

 

Билет 20. Классы. Конструкторы и деструкторы.

Если у класса есть конструктор, он вызывается всякий раз при создании объекта этого класса. Если у

класса есть деструктор, он вызывается всякий раз, когда уничтожается объект этого класса. Объект

может создаваться как:

[1] автоматический, который создается каждый раз, когда его описание встречается при

выполнении программы, и уничтожается по выходе из блока, в котором он описан;

[2] статический, который создается один раз при запуске программы и уничтожается при ее

завершении;

[3] объект в свободной памяти, который создается операцией new и уничтожается операцией

delete;

[4] объект-член, который создается в процессе создания другого класса или при создании массива,

элементом которого он является.

Кроме этого объект может создаваться, если в выражении явно используется его конструктор

или как временный объект. В обоих случаях такой объект не имеет имени.

Ø Конструктор представляет собой метод класса, который облегчает вашим программам инициализацию элементов данных класса.

Ø Конструктор имеет такое же имя, как и класс.

Ø Конструктор не имеет возвращаемого значения.

Ø Каждый раз, когда ваша программа создает переменную класса, C++ вызывает конструктор класса, если конструктор существует.

Ø Многие объекты могут распределять память для хранения информации; когда вы уничтожаете такой объект, C++ будет вызывать специальный деструктор, который может освобождать эту память, очищая ее после объекта.

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

Ø Деструктор не имеет возвращаемого значения.

 

29. Конструкторы и способы обращения к ним.

Конструктор представляет собой специальную функцию, которую C++ автоматически вызывает каждый раз при создании объекта. Обычное назначение конструктора заключается в инициализации элементов данных объекта. Конструктор имеет такое же имя, как и класс. Например, класс с именем file использует конструктор с именем file. Вы определяете конструктор внутри своей программы так же, как и любой метод класса. Единственное различие заключается в том, что конструктор не имеет возвращаемого значения. Когда вы позже объявляете объект, вы можете передавать параметры конструктору, как показано ниже:

class_name object(valuel, value2, value3)

Итак, конструкторы используются для создания объекта. Благодаря конструкторам разрабатываемые новые типы данных становятся такой неотъемлимой частью языка, как и встроенные типы. Конструктор определяет, каким образом новый объект типа класса будет создан, как будет проводиться выделение памяти и инициализация объекта. Его определение может включать инструкции для выделения памяти, присваивания значений элементам, преобразование типов, и все что угодно, необходимое для данного класса. При этом конструкторы наследуют имя своего класса:

       class sber_bank {           < Объявление класса

       private:

          double big_bucks;

       public:

          sber_bank(double bucks); < Конструктор

          void deposit(double bucks);

          double withdraw(double bucks);

       };

Разберем порядок описания конструктора:

             Селектор                  Используемый класс            Имя конструктора

                   sber_bank:: sber_bank(double bucks)

                    {

                        big_bucks = bucks; < Инициализация данных

                    }

Конструктор можно сделать встроенным:

       class sber_bank {

       private:

          double big_bucks;

       public:

          // Встроенный конструктор

          sber_bank(double bucks) { big_bucks = bucks; }

          void deposit(double bucks);

          double withdraw(double bucks);

       };

Вызов конструкторов

Конструкторы могут вызываться неявно - через обращение к функции элементу во время объявления объекта. Задавая объекту параметры, вы сообщаете о их передаче непосредственно конструктором:

       Имя                    Объект      класса                

          sber_bank counterfeit_bank_of_AZ(1000000.00);

                         Обусловлено вызовом конструктораКонструкторы могут вызываться во время, когда выполняется обращение к объекту. Так, конструктор вызывается всякий раз, когда обращаются к функции элементу объекта:

       void doit(void)

       {

         sber_bank telly(1000.0); < Здесь вызывается конструктор

        ...

Количество конструкторов неограниченно. Существуют также конструкторы копирования и т.д. Компилятор сам определяет какой именно конструктор вызывается.

 

При создании объектов одной из наиболее широко используемых операций которую вы будете выполнять в ваших программах, является инициализация элементов данных объекта. Как вы узнали из урока 22, единственным способом, с помощью которого вы можете обратиться к частным элементам данных, является использование функций класса. Чтобы упростить процесс инициализации элементов данных класса, C++ использует специальную функцию, называемую конструктором, которая запускается для каждого создаваемого вами объекта. Подобным образом C++ обеспечивает функцию, называемую деструктором, которая запускается при уничтожении объекта. В данном уроке конструктор и деструктор рассматриваются более подробно. К концу этого урока вы освоите следующие основные концепции:

  • Конструктор представляет собой метод класса, который облегчает вашим программам инициализацию элементов данных класса.
  • Конструктор имеет такое же имя, как и класс.
  • Конструктор не имеет возвращаемого значения.
  • Каждый раз, когда ваша программа создает переменную класса, C++ вызывает конструктор класса, если конструктор существует.
  • Многие объекты могут распределять память для хранения информации; когда вы уничтожаете такой объект, C++ будет вызывать специальный деструктор, который может освобождать эту память, очищая ее после объекта.
  • Деструктор имеет такое же имя, как и класс, за исключением того, что вы должны предварять его имя символом тильды (~).
  • Деструктор не имеет возвращаемого значения.

Термины конструктор и деструктор не должны вас пугать. Вместо этого представьте конструктор как функцию, которая помогает вам строить (конструировать) объект. Подобно этому, деструктор представляет собой функцию, которая помогает вам уничтожать объект. Деструктор обычно используется, если при уничтожении объекта нужно освободить память, которую занимал объект.






















Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: