Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Глава 9. Динамическое выделение памятиСодержание книги
Поиск на нашем сайте Динамическое выделение памяти Создание и поддержание динамических структур данных требует динамического распределения памяти: возможности в процессе выполнения программы изменения области памяти для хранения новых узлов и освобождения ресурсов памяти, в которых уже нет необходимости. Пределы динамического выделения памяти ограничены только объемом доступной физической или виртуальной памяти в системах с виртуальной памятью. Операции new и delete – основные для работы с динамической памятью. Операция new принимает в качестве аргумента тип динамического размещения объекта и возвращает указатель на объект этого типа. Пример 1 Node *newptr = new Node[10]; // выделяет в памяти sizeof(Node) байтов и сохраняет указатель на область памяти указателем Ptr. Число 10 – число размещенных объектов данных. Пример 2 Main () { int * p = new int; cout << "sizeof(int) = " << sizeof(int) "\n"; } Для освобождения памяти используется оператор delete. Указатель newptr не удаляется, а исчезает область памяти, на которую указывает newptr. Пример 3 delete[] newptr; Пример 4 main() { char *p = new char[100]; char *q = new char[100]; delete p; delete q; } Типичные ошибки: · может быть ссылка на область памяти, которая уже была освобождена · оператором delete освобождать память, которая не была выделена new · не осуществляется возвращение динамически выделенной памяти, когда эта память уже не требуется. Это может явиться причиной переполнения памяти (утечка памяти) · предположение о том, что размер объекта класса является простой суммой объектов его элементов данных. Это не так по причине различных машинно-зависимых требований по выравниванию границ области памяти. · необходимо проверять, не вернула функция new нулевой указатель Пример 5 /* распределить память под 1-мерный массив указателей на беззнаковые целые размером degree по адресу tab используя оператор new */ tab=new unsigned *(degree); /* под каждый указатель полученного массива указателей распределить одномерный массив беззнаковых целых из degree элементов, используя оператор new в цикле */ for (int i=0; i<degree;i++) tab[i]=new unsigned(degree); /* освободить память, распределенную под degree одномерных массивов беззнаковых целых (из degree элементов каждый) по адресам от tab[0] до tab[degree-1] */ for (int i=0; i<degree; i++) delete [degree](tab[i]); /* освободить память, распределенную под 1-мерный массив указателей на беззнаковые целые, состоящий из degree указателей по адресу tab */ delete [degree]tab;
Глава 10. Перегрузка операций Перегрузка операций Функция-оператор (операторная функция, функциональная операция) может быть определена как внутри описания класса, так и вне его. Различают два вида операторных функций: · простую (определяется вне класса, может быть одноместной или двухместной) · компонентную (определяется в классе. У нее первый аргумент представляет собой объект класса, заданный неявно. Она может быть одноместной – не имеет явных аргументов, либо двухместной – с одним аргументом)
<тип результата> - тип возвращаемого значения (имеет тот же тип, что и класс, но возможен и иной тип значения). Следует помнить, что нельзя перегружать следующие операторы:.::.*? sizeof и операторы препроцессора # и ## Перегрузка операций подчинена следующим правилам: · при перегрузке операций сохраняется количество аргументов, приоритеты операций и правила ассоциации, используемые в стандартных типах данных · для стандартных типов данных переопределить операции нельзя · функциональные операции не могут иметь аргументов по умолчанию · функциональные операции наследуются (кроме операции присваивания =) · функциональные операции не могут определяться как static Функциональную операцию можно определить тремя способами: · как метод класса · как дружественную функцию · как обычную функцию Если операторная функция определяется вторым и третьим способами, то она должна принимать хотя бы один аргумент, имеющий тип класса, либо указатель или ссылку на класс. Особый случай операторной функции: когда первый параметр имеет стандартный тип. В этом случае она не определяется как метод класса.
Формы вызова операторной функции:
Перегрузка унарных операций Унарная операторная функция может быть определена как внутри, так и вне класса. Унарная функциональная операция, определенная внутри класса, должна быть представлена с помощью нестатического метода. При этом операндом является вызывающий её объект. Пример 1 Class monstr { monstr &operator ++() { ++health; return *this; } }; monstr Vasia; cout<<(++Vasia).get_health(); Если унарная операция определена вне класса, она должна иметь один параметр - типа класса Пример 2 Class monstr { friend monstr &operator ++(monstr &M); }; monstr &operator ++ (monstr &M) { ++M.health; return M; } Если не описывать функцию внутри класса как дружественную функцию, нужно учитывать доступность полей. В данном примере поле health не доступно извне, т.к. описано как private. Для его изменения следует использовать специальные методы. Введем в класс monstr специальный метод change_health, который будет позволять менять значение health: Пример 3 void change_health(int he) {health =he;} При вводе этого метода можно пере+гружать оператор инкрементации с помощью обычной функции, описанной вне класса: Пример 4 monstr &operator ++ (monstr &M) { int h=M.get_health(); h++; M.change_health(h); return M; } В случае использования оператора постфиксного инкремента и декремента дадим им первый параметр типа int. Он используется для того, чтобы отличить их от префиксной формы. Пример 5 const monstr operator ++ (int) { monstr M(*this); health++; /* Лучше ++(*this); */ return M; } monstr Vasia; cout << (Vasia++).get_health();
|
||||||||||||||||||
|
Последнее изменение этой страницы: 2021-07-18; просмотров: 153; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.146 (0.007 с.) |