Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчёт_Классы.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
49.82 Кб
Скачать

Перегрузка операций и дружественные функции

Листинг 4: Пример класса стек с перезагрузкой операций

#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 operator=(const Stack &st);

friend std::istream &operator>>(std::istream &is, Stack &st);

friend std::ostream &operator<<(std::ostream &os, Stack &st);

friend void operator<<( Stack &st, DType obj);

friend void operator>>(Stack &st, DType &obj);

};

}

Пример реализации:

#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;

}

std::istream &operator>>(std::istream &is, Stack &st)

{

if (st.top == st.size-1){

std::cerr << "Стек полон.\n";

return is;

}

is >> st.stck[++st.top];

return is;

}

std::ostream &operator<<(std::ostream &os, Stack &st)

{

if (st.top == -1){

std::cerr << "Стек пуст.\n";

return os;

}

os << st.stck[st.top--];

return os;

}

void operator<<( Stack &st, DType obj)

{

if (st.top == st.size-1){

std::cerr << "Стек полон.\n";

return;

}

st.stck[++st.top] = obj;

}

void operator>>(Stack &st, DType &obj)

{

if (st.top == -1){

std::cerr << "Стек пуст.\n";

return;

}

obj = st.stck[st.top--];

}

Stack Stack::operator=(const Stack &st)

{

delete [] stck;

top = st.top;

size = st.size;

stck = new DType[size];

for(int i=0; i<size; i++)

stck[i] = st.stck[i];

return *this;

}

}

Пример использования:

#include <iostream>

#include "stack_v2.h"

using namespace std;

int main(int argc, char *argv[])

{

system("chcp 65001");

stk::Stack st(5);

for (int i=0; i< st.get_size(); i++){

st << i;

}

stk::Stack st2 = st;

cout << st2 << endl;

st2 = st;

int temp;

for (int i=0; i< st.get_size(); i++){

cout << "st: " << st << endl;

st2 >> temp;

cout << "st2: "<< temp << endl;

}

return 0;

}

Результат:

4

st: 4

st2: 4

st: 3

st2: 3

st: 2

st2: 2

st: 1

st2: 1

st: 0

st2: 0

Перегрузка операций

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

тип operator операция (список параметров) {тело функции }

Нельзя перегружать:

. .* ?: :: # ## sizeof

Правила:

  • при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;

  • для стандартных типов данных переопределять операции нельзя;

  • функции-операции не могут иметь аргументов по умолчанию;

  • функции-операции наследуются (за исключением =*);

  • функции-операции не могут определяться как static.

Функцию-операцию можно определить тремя способами: она должна быть либо методом класса, либо дружественной функцией класса, либо обычной функцией.

Дружественная функция

Дружественные функции применяются для доступа к скрытым полям класса и представляют собой альтернативу методам.

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

Правила:

  • Дружественная функция объявляется внутри класса, к элементам которого ей нужен доступ, с ключевым словом friend. В качестве параметра ей должен передаваться объект или ссылка на объект класса, поскольку указатель this ей не передается.

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

  • Одна функция может быть дружественной сразу нескольким классами

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]