Конструкторы и деструкторы
Листинг 3. Пример класса стек с конструктором
//stack.h
#pragma once
#include <iostream>
namespace stk{
//тип стека
typedef int DType;
class Stack{
DType *stck;
int top;
int size;
public:
//Конструктор
Stack(int s);
Stack(const Stack &st);
~Stack();
// операции модификации стека
void push(const DType &item);
DType pop();
void clear();
// доступ к стеку
DType peek (void) const;
int get_size() const { return size;}
// методы проверки стека
bool isEmpty() const;
bool isFull() const; // реализация массива
};
}
Пример реализации:
//stack.cpp
#include "stack.h"
namespace stk{
//Конструктор
Stack::Stack(int s)
{
top = -1;
stck = new DType[size];
size = s;
}
Stack::Stack(const Stack &st)
{
top = st.top;
size = st.size;
stck = new DType[size];
for(int i=0; i<size; i++)
stck[i] = st.stck[i];
}
Stack::~Stack()
{
delete [] stck;
}
void Stack::push(const DType &item)
{
if (top == size-1){
std::cerr << "Стек полон.\n";
return;
}
stck[++top] = item;
}
DType Stack::pop()
{
if (top == -1){
std::cerr << "Стек пуст.\n";
return 0;
}
return stck[top--];
}
void Stack::clear(void)
{
top = -1;
}
DType Stack::peek() const
{
if (top == -1)
{
std::cerr << "Стэк пуст!\n";
exit(1);
}
return stck[top];
}
bool Stack::isEmpty() const
{
return top == -1;
}
bool Stack::isFull() const
{
return top == size-1;
}
}
Пример использовании:
#include <iostream>
#include "stack.h"
using namespace std;
int main(int argc, char *argv[])
{
system("chcp 65001");
stk::Stack st(5); // stk::Stack st = 5;
for (int i=0; i< st.get_size(); i++){
st.push(i+1);
}
cout << st.peek() << endl;
stk::Stack st2 = st;
for (int i=0; i< st.get_size(); i++){
cout << "st: " << st.pop() << endl;
cout << "st2: "<< st2.pop() << endl;
}
return 0;
}
Результат:
5
st: 5
st2: 5
st: 4
st2: 4
st: 3
st2: 3
st: 2
st2: 2
st: 1
st2: 1
Конструктор предназначен для инициализации объекта и вызывается автоматически при его создании:
Свойства:
Конструктор не возвращает значения
Конструктор можно перегружать
Конструктор, вызываемый без параметров, называется конструктором по умолчанию.
Параметры конструктора могут иметь любой тип, кроме этого же класса.
Если программист не указал ни одного конструктора, компилятор создает его автоматически.
Конструкторы не наследуются.
Конструкторы нельзя описывать с модификаторами const. virtual и static.
Конструкторы глобальных объектов вызываются до вызова функции main.
Синтаксис
Имя класса ([параметры]){}
Деструктор — это особый вид метода, применяющийся для освобождения памяти, занимаемой объектом. Деструктор вызывается автоматически, когда объект выходит из области видимости:
• для локальных объектов — при выходе из блока, в котором они объявлены;
• для глобальных — как часть процедуры выхода из main:
• для объектов, заданных через указатели^ деструктор вызывается неявно при использовании операции delete.
Имя деструктора начинается с тильды (~), за которой следует имя класса.
Свойства:
не имеет аргументов и возвращаемого значения;
не может быть объявлен как const или static;
не наследуется;
может быть виртуальным
Если деструктор явным образом не определен, компилятор автоматически создает пустой деструктор.
Синтаксис
~Имя класса ([параметры){}
Конструктор копирования
Конструктор копирования — это специальный вид конструктора, получающий в качестве единственного параметра указатель на объект этого же класса:
Имя класса (const Имя класса &obj) {
//Тело конструктора
}
Конструктор копирования вызывается:
при описании нового объекта с инициализацией другим объектом;
при передаче объекта в функцию по значению;
при возврате объекта из функции^
Если не указано ни одного конструктора копирования, компилятор создает его автоматически. Такой конструктор выполняет поэлементное копирование полей. Если класс содержит указатели или ссылки, это, скорее всего, будет неправильным, поскольку и копия, и оригинал будут указывать на одну и ту же область памяти.
Любой конструктор класса, принимающий один параметр какого-либо другого типа, называется конструктором преобразования, поскольку он осуществляет преобразование из типа параметра в тип этого класса.
