Структуры
Свободная память
Унарные операторы 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, как написано выше >
Используется оператор разрешения области видимости “::” .