Введение в язык Си++



             

Структуры и Объединения


По определению struct - это просто класс, все члены которого общие, то есть

struct s { ...

есть просто сокращенная запись

class s { public: ...

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

Именованное объединение определяется как struct, в которой все члены имеют один и тот же адрес (см. #с.8.5.13). Если известно, что в каждый момент времени нужно только одно значение из структуры, то объединение может сэкономить пространство. Например, можно определить объединение для хранения лексических символов C компилятора:

union tok_val { char* p; // строка char v[8]; // идентификатор (максимум 8 char) long i; // целые значения double d; // значения с плавающей точкой };

Сложность состоит в том, что компилятор, вообще говоря, не знает, какой член используется в каждый данный момент, поэтому надлежащая проверка типа невозможна. Например:

void strange(int i) { tok_val x; if (i) x.p = "2"; else x.d = 2; sqrt(x.d); // ошибка если i != 0 }

Кроме того, объединение, определенное так, как это, нельзя инициализировать. Например:

tok_val curr_val = 12; // ошибка: int присваивается tok_val'у

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

union tok_val { char* p; // строка char v[8]; // идентификатор (максимум 8 char) long i; // целые значения double d; // значения с плавающей точкой

tok_val(char*); // должна выбрать между p и v tok_val(int ii) { i = ii; } tok_val() { d = dd; } };

Это позволяет справляться с теми ситуациями, когда типы членов могут быть разрешены по правилам для перегрузки имени функции (см. и #6.3.3). Например:

void f() { tok_val a = 10; // a.i = 10 tok_val b = 10.0; // b.d = 10.0 }

Когда это невозможно (для таких типов, как char* и char[8], int и char, и т.п.), нужный член может быть найден только посредством анализа инициализатора в ходе выполнения или с помощью задания дополнительного параметра. Например:

tok_val::tok_val(char* pp) { if (strlen(pp)

Таких ситуаций вообще-то лучше избегать.




Содержание  Назад  Вперед