Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Перегрузка операций (операторов). Перегрузка операторов доступа к членам класса. Перегрузка операторов new и delete. Функции преобразования типа.

Читайте также:
  1. II Цель, задачи, функции и принципы портфолио.
  2. II. Функции школьной формы
  3. II.Синдром дисфункции синусового узла (СССУ) I 49.5
  4. Lt;question>Укажите функции научного стиля?
  5. V. Трудовая деятельность класса.
  6. А) Основные психофизические функции
  7. А) широта семантических связей между членами словосочетаний.

Ключевое слово operator предоставляет объявление функции, указывающей что operator-symbol означает при его применении к экземплярам класса. Это предоставляет оператору многозначность или "перегружает" его. Компилятор различает разные виды одного и того же оператора, изучая типы его операндов.

type operator operator-symbol (parameter-list)

Доступом к члену класса можно управлять путем перегрузки оператора доступа к члену (–>). В данном случае этот оператор считается унарным оператором, и функция перегруженного оператора должна быть функцией-членом класса. Поэтому объявление такой функции выглядит следующим образом.

class-type *operator–>()

Перегрузке могут быть подвергнуты следующие унарные операторы.

! (логическое НЕ) & (взятие адреса) ~ (дополнение до единицы) * (разыменование указателя) + (унарный плюс) - (унарное отрицание) ++ (инкремент) -- (декремент) операторы преобразования

Имеется возможность перегрузить new и delete. Это можно сделать в том случае, если необходи­мо использовать какой-то особый способ выделения памяти. Например, может понадобиться процедура выделения памяти, автоматически использующая дисковый файл в качестве виртуаль­ной памяти в том случае, когда куча оказывается исчерпанной. Какой бы ни была причина, осуществить такую перегрузку очень просто.

Для перегрузки операторов new и delete может использоваться следующий формат:
void *operator new(size_t размер)
{
// выполнение выделения
return указатель_на_память;
}
void operator delete(void *p)
{
// освобождение памяти, на которую указывает р
}

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

Функция delete получает указатель на область памяти, которую необходимо освободить. Она обязана освободить эту память. Для перегрузки операторов new и delete применительно к масси­вам надо использовать следующий формат:
void *operator new[](size_t размер)
{
// выполнение выделения
return указатель_на_память;
}
void operator delete[](void *р)
{
// освобождение памяти, на которую указывает р
}

Можно перегрузить операторы new и delete глобально или относительно класса. Для того что­бы перегрузить их по отношению к классу, просто надо сделать их функциями-членами этого класса.

Преобразование позволяет получить новое значение некоторого типа из значения другого типа. Стандартные преобразования основаны на языке C++ и поддерживают его встроенные типы; кроме того, можно создать пользовательские преобразования для выполнения преобразования в, из или между пользовательскими типами.

Стандартные преобразования выполняют преобразование между встроенными типами, между указателями или ссылками на типы, связанные наследованием, в и из указателей void и в пустой указатель. Для получения дополнительной информации см. Стандартные преобразования. Пользовательские преобразования выполняют преобразование между пользовательскими типами или между пользовательскими и встроенными типами. Их можно реализовать как conversion constructors илиconversion functions.

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

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

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

Если не удается выполнить неявное преобразование с помощью стандартного преобразования, компилятор может использовать пользовательское преобразование, за которым (при необходимости) будет следовать дополнительное стандартное преобразование.

Если на сайте преобразования есть два и более пользовательских преобразования, выполняющих одно преобразование, преобразование называется неоднозначным. Неоднозначность подразумевает ошибку, так как компилятор не может определить, какое из доступных преобразований выбрать. Тем не менее, не будет ошибкой определить несколько способов выполнения одного преобразования, так как набор доступных преобразований может отличаться в разных участках исходного кода, например в зависимости от того, какие файлы заголовков входят в исходный файл. Пока на сайте преобразования доступно только одно преобразование, о неоднозначности речь не идет. Существует несколько путей возникновения неоднозначных преобразований, однако самые распространенные перечислены ниже.

Множественное наследование. Преобразование определено в нескольких базовых классах. Для получения дополнительной информации см. Неоднозначность.

Вызов неоднозначной функции. Преобразование определено как конструктор преобразования типа целевого объекта и как функция преобразования типа источника. Для получения дополнительной информации см. conversion functions.

Неоднозначность, как правило, можно устранить, просто более полно указав имя соответствующего типа или выполнив явное приведение для пояснения намерения.

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

Функции преобразования определяют преобразования из пользовательского в другие типы. Эти функции иногда называют "операторами приведения", так как они, наряду с конструкторами преобразования, вызываются, когда значение приводится к другому типу. В следующем примере показана функция преобразования, которая преобразует пользовательский тип Money во встроенный тип double.

#include <iostream>

class Money

{

public:

Money(): amount{ 0.0 } {};

Money(double _amount): amount{ _amount } {};

operator double() const { return amount; }

private:

double amount;

};

void display_balance(const Money balance)

{

std::cout << "The balance is: " << balance << std::endl;

}

Обратите внимание, что переменная-член amount объявлена закрытой, а открытая функция преобразования в тип double добавлена только для возврата значения переменной amount. В функции display_balance неявное преобразование возникает, когда значение balance направляется в стандартный вывод с помощью оператора вставки в поток <<. Поскольку оператор вставки в поток не определен для пользовательского типа Money, но имеется для встроенного типа double, компилятор может использовать функцию преобразования Money в double, чтобы удовлетворить требования оператора вставки в поток.

Функции преобразования наследуются производными классами. Функции преобразования в производном классе переопределяют наследуемую функцию преобразования, только когда выполняют преобразование в точно такой же тип. Например, пользовательская функция преобразования производного классаoperator int не переопределяет (и даже вообще не влияет) на пользовательскую функцию базового класса operator short, даже если стандартное преобразование определяет отношение преобразования между int и short.

Объявление функций преобразования

Следующие правила применяются к объявлению функции преобразования.

Целевой тип преобразования должен быть объявлен до объявления функции преобразования. Классы, структуры, перечисления и определения типа нельзя объявлять в объявлении функции преобразования.

operator struct String { char string_storage; }() // illegal

Функции преобразования не принимают аргументов. Указание любых параметров в объявлении является ошибкой.

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

Функции преобразования могут быть виртуальными.

Функции преобразования могут быть явными.


Дата добавления: 2015-09-03; просмотров: 177 | Нарушение авторских прав


Читайте в этой же книге: Неполный конструктор | Перезагрузка конструкторов | Перегрузка операций (операторов). Понятие перегрузки операторов. Синтаксис перегрузки операции. Перегрузка бинарных операторов. | Перегрузка операций (операторов). Перегрузка операторов отношения и логических операторов. Перегрузка оператора присваивания. Перегрузка унарных операторов. | Перегрузка операций (операторов). Перегрузка операторов инкремента и декремента. Перегрузка оператора индексирования. Перегрузка оператора вызова функции. | Полиморфизм и виртуальные функции. Применение динамического полиморфизма. Виртуальные деструкторы. Абстрактные классы и чисто виртуальные функции. | Длина самого длинного слова 10 | Самое длинное слово beautiful | Строковые потоки | Состояние формата (ОТНОСИТСЯ К ПОСЛЕДНЕМУ ВОПРОСУ, КОТОРЫЙ 24) |
<== предыдущая страница | следующая страница ==>
УПРАВЛЕНИЕ «НАМЕРЕНИЕМ». ТРЕТЬЯ ТОЧКА.| Полиморфизм и виртуальные функции. Раннее и позднее связывание. Динамический полиморфизм. Виртуальные функции. Виртуальные и невиртуальные функции.

mybiblioteka.su - 2015-2024 год. (0.012 сек.)