ОБЪЕДИНЕНИЯ

 

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

Объединение создается при помощи ключевого слова union:

union имя_типа

{

тип_элемента1 имя_элемента1;

тип_элемента2 имя_элемента2;

тип_элемента3 имя_элемента3;

};

К членам объединения можно обращаться так же, как и к членам структур, либо через операцию “точка”, либо через операцию “–>” – для указателей:

union many_types

{

char c[4];

int ivalue[2];

float fvalue;

} type1;

type1.fvalue=1.5;

printf(“%i %i”,type1.ivalue[0],type1.ivalue[1]);

 

 

ДОПОЛНИТЕЛЬНЫЕ СРЕДСТВА (TYPEDEF И ENUM)

 

При помощи оператора typedef можно связать новые типы данных с существующими:

typedef double real;

 

После такого описания можно использовать real вместо double. Использовать typedef необходимо с осторожностью. Слишком много новых типов могут ухудшить читаемость программы. Перечисляемый тип данных enum позволяет определить список последовательных целых чисел, каждое из которых имеет собственное имя. Объявление перечисляемого типа выглядит следующим образом:

enum имя_типа {имя1=знач1, имя2=знач2, имя3=знач3, …}переменная;

 

Здесь имя1, имя2,… – это имена констант. Им можно присваивать целочисленные значения. Если значения отсутствуют, то предполагается, что они последовательно увеличиваются на единицу, начинаясь с нуля. Память под эти константы во время выполнения не выделяется, поэтому удобно использовать этот оператор для создания констант, если не указывать имя_типа и переменную enum (с28=28, с29,с30,c31).

Тип enum часто используется, когда информацию можно представить списком целых значений, подобно номерам дней недели или месяцев в году:

 

enum months

{Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}

current_month;

current_month=Dec; //используется константа 12

int diff=(int)current_month-2;

//тип enum автоматически не преобразуется в int

 

Поскольку имена эквивалентны последовательным целым значениям, то с ними можно выполнять арифметические операции. Фактически в данном примере переменной current_month присваивается целочисленное значение 12.

 

СИНТАКСИС И ПРАВИЛА ДЛЯ КЛАССОВ С++

 

Описание класса С++ начинается с ключевого слова class. Оформление определения класса очень похоже на описание struct.

class имя_класса

{

тип переменная1;

тип переменная2;

функция-член1

функция-член2

public:

тип переменная3;

тип переменная4;

функция-член3

функция-член4

};

 

По умолчанию члены класса являются частными (private). Они доступны только функциям-членам. После объявления public следуют данные и функции, доступные внешним для класса функциям. Внутри описания класса может быть указан только прототип метода. Сам метод может быть написан вне описания и даже в другом файле. В этом случае заголовок метода выглядит следующим образом:

возвращаемыйТип имяКласса :: имяМетода (список аргументов) {код метода}

 

На что здесь следует обратить внимание? Имя_класса с этого момента становится новым именем типа данных, которое используется для объявления объектов класса.

Члены класса – это переменные состояния и методы этого класса, иными словами, членами класса могут быть как переменные, так и функции. Функции и переменные, объявленные внутри объявления класса, становятся членами этого класса. Функции-члены класса будем называть методами этого класса.

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

 

INLINE МЕТОДЫ

 

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

Пример:

inline double math_operation::getSquareRoot()

{

return sqrt(data);

}

 

Действует следующее соглашение, если код метода написан непосредственно внутри описания класса, то он автоматически считается inline.

 

УКАЗАТЕЛЬ THIS

 

При описании класса автоматически объявляется переменная с именем this. Она указывает на текущий экземпляр класса:

ИмяКласса *this;

 

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

 

КОНСТРУКТОРЫ И ДЕСТРУКТОРЫ

 

Особенность ООП в том, что некоторые методы выполняются неявно. К ним относятся конструктор и деструктор. Конструкторы в языке С++ имеют имена, совпадающие с именем класса. Конструктор может быть определен пользователем, или компилятор сам сгенерирует конструктор по умолчанию. Конструктор может вызываться явно или неявно. Компилятор сам автоматически вызывает соответствующий конструктор там, где Вы определяете новый объект класса.

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

Конструкториспользуется для инициализации переменных класса и для выделения памяти под динамические массивы. Он выполняется автоматически при создании представителя класса. Конструктор имеет имя, совпадающее с именем класса. Тип возвращаемого результата для конструктора не указывается. Одновременно может быть определено несколько конструкторов, которые отличаются количеством и типом аргументов. Имеется как минимум три конструктора:

- конструктор без параметров (используемый по умолчанию),

- конструктор с параметрами,

- конструктор, создающий копию объекта.

Если они не включены в описание класса, то компилятор создает их самостоятельно.

Деструктор вызывается при уничтожении объекта. Он обычно используется для освобождения памяти. Деструктор имеет имя, совпадающее с именем класса, но впереди имени ставится знак ‘~’ (тильда), параметров не имеет.

Ранее было указано, что конструкторы могут иметь параметры. При реализации наследования допускается передача параметров для конструкторов производного и базового класса. Если параметрами обладает только конструктор производного класса, то аргументы передаются обычным способом. Однако при необходимости передать аргумент конструктору родительского класса требуется несколько большее усилие. Прежде всего нужно позаботиться о том, чтобы передать из конструктора производного класса конструктору базового класса. Для этого используется расширенная запись конструктора производного класса.

конструктор_производного_класса (список формальных параметров): конструктор_базового_класса (список фактических параметров)

{

... // тело конструктора производного класса

}

 

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

 

ПЕРЕГРУЗКА МЕТОДОВ КЛАССА

 

Методы в классе могут иметь одинаковые имена, если они различаются количеством и/или типом аргументов. Такое свойство называется перегрузкой методов (или совмещением). Использование нескольких конструкторов, в частности, возможно благодаря этому свойству. Пример:

class module

{

public:

//вычисление модуля целого числа

int mod(int n){return abs(n);}

//вычисление модуля действительного числа

double mod(double n){return fabs(n);}

};

void main()

{

module m;

int a=-10;

cout<<m.mod(a); //вызывается первый метод

double b=-1.5;

cout<<m.mod(b); //вызывается второй метод

}

 

ПЕРЕГРУЗКА ОПЕРАЦИЙ

 

Для любого класса можно определить свои собственные операции. Такая возможность называется перегрузкой операций. Можно перегружать все арифметические и логические операции, операции присваивания, квадратные и круглые скобки, операции new и delete. Синтаксис определения метода, перегружающего операцию:

ВозвращаемыйТип operator перегружаемая_Операция (параметры){код}

 

Пример перегрузки операции сложения:

coins coins::operator+(coins a)

{

coins res;

res.number=this->number+a.number;

return res;

}