Изменения

Перейти к: навигация, поиск

Участник:Yulya3102/Плюсы2сем

5633 байта добавлено, 23:39, 9 марта 2013
перегрузка операторов, ADL
=== callback'и, способы фиксации аргументов у callback'ов ===
=== наследование, виртуальные функции, таблицы виртуальных функций ===
Виртуальный метод (виртуальная функция) — метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения.
 
Базовый класс может и не предоставлять реализации виртуального метода, а только декларировать его существование. Такие методы без реализации называются «чистыми виртуальными» (перевод англ. pure virtual) или абстрактными. Класс, содержащий хотя бы один такой метод, тоже будет абстрактным. Объект такого класса создать нельзя. Наследники абстрактного класса должны предоставить реализацию для всех его абстрактных методов, иначе они, в свою очередь, будут абстрактными классами.
 
Для каждого класса, имеющего хотя бы один виртуальный метод, создаётся таблица виртуальных методов. Каждый объект хранит указатель на таблицу своего класса. Для вызова виртуального метода используется такой механизм: из объекта берётся указатель на соответствующую таблицу виртуальных методов, а из неё, по фиксированному смещению, — указатель на реализацию метода, используемого для данного класса. При использовании множественного наследования или интерфейсов ситуация несколько усложняется за счёт того, что таблица виртуальных методов становится нелинейной.
 
=== dynamic_cast ===
В отличие от обычного приведения типа в стиле Си, проверка корректности приведения типов производится во время выполнения программы. Оператор dynamic_cast может быть применён к указателям или ссылкам. В случае если осуществляется преобразование указателя к типу данных, который не является фактическим типом объекта, в результате преобразования будет получен нулевой указатель. При работе с ссылками при невозможности преобразования типа будет сгенерировано исключение std::bad_cast.
=== проблемы сишного typecast'а с неполными типами и несколькими базами===Что делает приведение типов в стиле С: пытается использовать static_cast, если не получается, использует reinterpret_cast. Далее, если нужно, использует const_cast .=== static_cast ===
Может быть использован для приведения одного типа к другому. Если это встроенные типы, то будут использованы встроенные в C++ правила их приведения. Если это типы, определенные программистом, то будут использованы правила приведения, определенные программистом.
static_cast между указателями корректно, только если один из указателей - это указатель на void или если это приведение между объектами классов, где один класс является наследником другого. То есть для приведения к какому-либо типу от void*, который возвращает malloc, следует использовать static_cast.
Если приведение не удалось, возникнет ошибка на этапе компиляции. Однако, если это приведение между указателями на объекты классов вниз по иерархии и оно не удалось, результат операции undefined. То есть, возможно такое приведение: static_cast<Derived*>(pBase), даже если pBase не указывает на Derived, но программа при этом будет вести себя странно.
=== const_cast===Самое простое приведение типов. Убирает так называемые cv спецификаторы (cv qualifiers), то есть const и volatile. volatile встречается не очень часто, так что более известно как приведение типов, предназначенное для убирания const. Если приведение типов не удалось, выдается ошибка на этапе компиляции.При использовании остальных приведений типов cv спецификаторы останутся как были. int i; const int * pi = &i; // *pi имеет тип const int, // но pi указывает на int, который константным не является int* j = const_cast<int *> (pi); === reinterpret_cast ===Самое нахальное приведение типов. Не портируемо, результат может быть некорректным, никаких проверок не делается. Считается, что вы лучше компилятора знаете как на самом деле обстоят дела, а он тихо подчиняется. Не может быть приведено одно значение к другому значению. Обычно используется, чтобы привести указатель к указателю, указатель к целому, целое к указателю. Умеет также работать со ссылками.  reinterpret_cast<whatever *>(some *) reinterpret_cast<integer_expression>(some *) reinterpret_cast<whatever *>(integer_expression) Чтобы использовать reinterpret_cast нужны очень и очень веские причины. Используется, например, при приведении указателей на функции. 
=== зачем нужно виртуальное наследование (несколько баз с разными адресами у одного класса, typecast'ы, исключения) ===
=== виртуальное наследование ===
=== зачем нужны namespace'ы ===
Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name. === namespace'ы, using declaration, ====== using directive, === using namespace namespace_name;Делает все объекты из namespace_name доступными в текущем scope  namespace a { int v; } namespace b { int v; } И два случая: { using a::v; using namespace b; // ошибки нет } { using a::v; using b::v; // ошибка из-за повторного объявления } === namespace aliases ===We can declare alternate names for existing namespaces according to the following format:  namespace new_name = current_name; 
=== перегрузка операторов, ADL ===
In the C++ programming language, argument-dependent lookup (ADL), or argument-dependent name lookup, applies to the lookup of an unqualified function name depending on the types of the arguments given to the function call.
namespace NS
{
class A {};
void f( A *&, int ) {}
}
int main()
{
NS::A *a;
f( a, 0 ); //calls NS::f
}
 
=== зачем нужны шаблоны ===
=== базовое представление о шаблонах ===
355
правок

Навигация