- •Ооп. Абстракция, полиморфизм, наследование, инкапсуляция
- •Методы класса: классификация методов, доступ к членам класса, неявный параметр this. Определение и реализация методов. Использование методов для экземпляров класса.
- •Перегрузка функций: правила перегрузки, выбор функции. Использование перегруженных функций.
- •Перегрузка операторов: правила перегрузки, перегрузка бинарных и унарных операторов. Использование перегруженных операторов. Понятие объектов функций (функторов).
- •Перегрузка унарных операторов
- •Бинарные операторы
- •Преобразования типа: назначение, использование. Правила преобразования типа. Возможные проблемы.
- •Оператор присваивания
- •Типы отношений между классами. Контейнерные классы: определение, видимость членов класса. Реализация и вызов конструкторов и деструкторов вложенных классов. Реализация и использование методов.
- •Вложенные классы
- •12. Понятие и назначение итераторов. Проектирование, реализация и использование итератора (на примере динамического списка).
Преобразования типа: назначение, использование. Правила преобразования типа. Возможные проблемы.
Существует два вида преобразований: Явное и неявное.
1.Присвоение "большему типу" значения "меньшего типа". Безопасное присвоение, гарантирует сохранение значения.
unsigned int UnsignedIntVal;
unsigned char UnsignedCharVal;
UnsignedIntVal = UnsignedCharVal;
2.Присвоение "меньшему типу" значения "большего типа". Потенциально опасное присвоение, грозит потерей информации.
int IntVal;
char CharVal;
CharVal = IntVal;
3.Преобразование значения из "меньшего типа" в "больший тип". Называется расширением типа.
(unsigned int)UnsignedCharVal;
4.Преобразование значения из "большего типа" в "меньший тип". Называется сужением типа. Является опасным преобразованием.
(char)IntVal;
Корректное выполнение действий со значениями различных типов в безопасных случаях и в ряде опасных случаев обеспечивается благодаря реализованной в C++ системе преобразования типов.
При трансляции выражений с различными типами операндов транслятор использует механизмы неявных преобразований, которые основываются на следующих правилах стандартных преобразований:
Присваивание значения объекту преобразует это значение к типу объекта.
unsigned int MyIntU;
MyIntU = 3.14159;
Эквивалентно
MyIntU = (unsigned int)3.14159;
Передача значения при вызове функции преобразует это значение в тип параметра функции. Он становится известен благодаря прототипу вызываемой функции.
void ff(int); // Прототип функции.
:::::
ff(3.14159);
Эквивалентно
ff((int)3.14159);
При этом на стадии трансляции возможно появление предупреждения о сужении типа.
В арифметическом выражении тип результата выражения определяется самым "широким" типом среди всех образующих выражение операндов. Этот тип называют результирующим типом выражения. К этому типу преобразуются все остальные операнды.
unsigned int MyIntU = 5;
…(MyIntU + 3.14159)…
Результирующим типом выражения здесь оказывается тип double, представленный в выражении литералом 3.14159. В процессе вычисления выражения значение переменной MyIntU преобразуется в 5.0, к которому прибавляется 3.14159.
Преобразование типа при вычислениях арифметических выражений применяется к копиям значений образующих выражение подвыражений. В процессе преобразования типов результаты преобразований подвыражениям не присваиваются.
unsigned int MyIntU = 5;
MyIntU = MyIntU + 3.14159;
Здесь имеют место два последовательных преобразования:
По ходу вычисления выражения значение переменной MyIntU расширяется до double и к расширенной копии значения 5.0 прибавляется 3.14159. После этого результирующее значение 8.14159, в соответствии с первым правилом, сужается до типа unsigned int. В результате чего получается значение 8, которое и присваивается переменной MyIntU.
Указатель на любой не являющийся константой тип можно присваивать указателю типа void*. Этот указатель способен адресовать объекты любого типа данных. Он используется всякий раз, когда неизвестен тип объекта.
int iVal;
int *p_iVal = 0;
char *p_chVal = 0;
void *p_Val;
const int *pc_iVal = &iVal;
p_Val = p_iVal;
p_Val = p_chVal;
// ПРАВИЛО 5 выполняется...
p_Val = pc_iVal;
//Ошибка: pc_iVal - указатель на константу.
const void *pcVal = pc_iVal;
/*
А здесь всё хорошо! Указателю на константу присвоен указатель на константу.
*/
Перед операцией разыменования указатель типа void* нужно явно преобразовать в указатель на конкретный тип, поскольку в этом случае отсутствует информация о типе, подсказывающая транслятору способ интерпретации битовой последовательности, представляемой указателем:
char *p_chValName = "Marina";
p_Val = p_chValName;
p_chVal = (char*)p_Val; /*Явное приведение.*/
Механизм неявных преобразований может быть отключён посредством явного указания в тексте программы требуемого преобразования типов.
Так, модификация ранее рассмотренного примера
MyIntU = MyIntU + (int)3.14159;
отключает механизм неявных преобразований и при вычислении значения переменной производится лишь одно преобразование типа, которое заключается в сужении типа значения литерала 3.14159.
*Тупо копия. Описать самому… бред.
Тут надо понять все это.
Вопрос равносильный «Что такое begin end?»
Классы, использующие свободную память: определение и реализация, использование экземпляров класса, возникающие проблемы. Копирующий конструктор и деструктор, перегрузка оператора присваивания: определение и использование.
// Не важно, какой тип будет использовать свободную память, юзается она new не
// зависимо от того класс это, структура или что-то другое.
////////////////
Оператор C++ new позволяет вашим программам распределять память во время выполнения. Для использования оператора new вам необходимо указать количество байтов памяти, которое требуется программе. Предположим, например, что вашей программе необходим 50-байтный массив. Используя оператор new, вы можете заказать эту память, как показано ниже:
char *buffer = new char[50];
Говоря кратко, если оператор new успешно выделяет память, он возвращает указатель на начало области этой памяти.
Зачем необходимо динамически распределять память с использованием new
Многие программы интенсивно используют массивы для хранения множества значений определенного типа. При проектировании своих программ программисты обычно пытаются объявить массивы с размерами, достаточными для удовлетворения будущих потребностей программы. К сожалению, если случится так, что потребности программы когда-нибудь превысят подобные ожидания программиста, то кому-то придется редактировать и перекомпилировать такую программу.
Конструктор – это метод класса, выполняющийся автоматически в момент создания объекта.
class _class
{
private: char data; public: class(char d):data(d) {} //конструктор (инициализирующий)
};
int main
{
int tt=666;
_class* _example = new _class(tt); //создание в свободной памяти экземпляра класса
cout << *_example -> data << endl; //выведем значение на экран
};
Копирующий конструктор – конструктор, копирующий один объект в другой, производится почленным копированием каждого элемента объекта.
class _class
{
private: char data; public: _class(_class& _example) { //копирующий конструктор
data = _example.data;
}
};
Если вашей программе больше не нужна выделенная память, она должна ее освободить, используя оператор delete. Для освобождения памяти с использованием оператора delete вы просто указываете этому оператору указатель на данную область памяти, как показано ниже:
delete pointer;
Деструктор представляет собой функцию, которую C++ автоматически запускает, когда он или ваша программа уничтожает объект. Деструктор имеет такое же имя, как и класс объекта; однако вы предваряете имя деструктора символом тильды (~), например ~_class. В своей программе вы определяете деструктор точно так же, как и любой другой метод класса.
class _class
{
private: char data; public: class(char d):data(d) {}
~_class (void) {} //указывает деструктор
};