Структуры

Свободная память

Унарные операторы new и delete служат для управления свободной памятью. Свободная память – это предоставляемая системой область памяти для объектов, время жизни которых напрямую управляется программистом. Программист создает объект с помощью ключевого слова new, а уничтожает его, используя delete. Это важно при работе с динамическими структурами данных, такими как списки и деревья. Еще один пример – создание объектов, которые используются после возвращения из функции, в которой они были созданы.

Оператор new принимает следующие формы:

new имя_типа

new имя_типа инициализатор

new имя_типа [выражение]

3 эффекта: выделяется надлежащий объем памяти для хранения указанного типа, инициализируе(ю)тся объект(ы) и возвращается базовый адрес объекта.

int *p, *q;

p=new int(5);

q=new int[10];

 

delete выражение

delete [] выражение

 

 

Массив – набор элементов одинакового типа.

Структура – набор элементов произвольных типов. Элемент структуры называется членом.

 

struct human{

char *name;

int age;

}; //точка с запятой после '}'

void f(){

human vova;

vova.name="Vova";

vova.age=70;

human piter={"Петя",100};

 

human *pp=&vova;

pp->age+=1;

}

Имя структуры (human) называется теговым именем и является типом. Можно объявлять переменные типа human (vova, piter). Их можно присваивать, передавать в качестве аргументов и возвращать в качестве значения функции.

Инициализация структуры (см.прог.)

Для доступа к членам структуры используется оператор «точка» – «.» (vova.name). Конструкция вида

переменная_структуры.имя_члена

используется как простая переменная.

Оператор указателя структуры. К объектам типа структуры часто обращаются посредством указателей с помощью оператора «->» :

указатель_на_структуру->имя_члена

Это эквивалентно

(*указатель_на_структуру).имя_члена

Структура – тип данных, определяемый пользователем.

Определим тип стека.

const int max_len=1000;

struct stack{

int top;

char s[max_len];

};

void reset(stack *stk){stk->top=0;}

void push(stack *stk, char c){stk->s[stk->top++]=c;}

char pop(stack *stk){return stk->s[--stk->top];}

bool is_empty(const stack *stk){return stk->top==0;}

bool is_full(const stack *stk){return stk->top==max_len;}

 

void use_stack()

{

stack s;

char str[]="Using Stack!!!";

int i=0;

cout<<str<<endl;

reset(&s);

while(str[i]) push(&s,str[i++]);

while(!is_empty(&s))cout<<pop(&s);

cout<<endl;

// pop(&s);

}

Напечатается строка в прямом и обратном порядках.

 

КЛАССЫ

В C++ существуют два вида типов: встроенные и типы классов. Встроенные типы включают в себя: char, int, double. Типы классов включают в себя, например: string, vector, istream, CFile, CDialog.

Свои типы классов может создавать и программист. Если они хорошо написаны, то их также легко использовать, как и встроенные типы.

Класс применяется для определения типов, соответствующих концепциям приложения.

 

Функции-члены класса

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

Перепишем стек: (сначала определим функции в пределах struct)

struct stack2

{

enum{ max_len=100};

int top;

char s[max_len];

 

void reset();

void push(char c);

char pop();

bool is_empty()const;

bool is_full()const;

};

 

void stack2::reset() {top=0;}

void stack2::push(char c){s[top++]=c;}

char stack2::pop(){return s[--top];}

bool stack2::is_empty()const {return top==0;}

bool stack2::is_full()const {return top==max_len;}

Эти функции отличаются тем, что могут обращаться к именам членов класса (top, s) «как есть», непосредственно.

void use_stack2()

{

stack2 s;

char str[]="Using Stack!!!";

int i=0;

cout<<str<<endl;

s.reset();

while(str[i])

s.push(str[i++]);

while(!s.is_empty())

cout<<s.pop();

cout<<endl;

// pop(&s);

}

При вызове функций-членов применительно к конкретному объекту типа stack2 они действуют на указанные члены именно этого (своего) объекта:

stack2 data, operands;//создаются 2 отдельных объекта со своими

//top и s[]

//но функции не отдельные, а одни и те же

data.reset();//data.top=0;

operands.reset();//operands.top=0;

stack2 *pstack=&operands;

pstack->push('A');//operands.s[operands.top++]='A'

Согласно правилам C++, если функция-член определена (а не только объявлена) в пределах структуры, то она является встраиваемой. Чтобы сделать ее обычной, нужно вынести ее определение за пределы структуры, а оставить только ее объявление (прототип).

 

< Определение stack2, как написано выше >

Используется оператор разрешения области видимости “::” .