Изменения

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

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

10 801 байт добавлено, 23:39, 9 марта 2013
перегрузка операторов, ADL
=== классы ===
{{TODO|t=union?}}
 
Класс — пользовательский тип, объявленный с помощью '''struct''', '''class''' или '''union'''.
 
{{TODO|t=А что вообще тут ещё может быть?}}
=== конструкторы ===
=== ссылки ===
=== разница между ссылками и указателями ===
[http://pastebin.com/FH9ChQUG]
 
=== l-value, r-value ===
[http://www.rsdn.ru/article/cpp/lvalue.xml]
 
=== перегрузка операторов ===
[http://habrahabr.ru/post/132014/]
 
=== оператор присваивания ===
Оператор присваивания генерируется компилятором. Генерируемый компилятором код выполняет поверхностное копирование всех полей (что может быть не очень подходящим вариантом).
 
Оператор присваивания вызывается на уже проинициализированном объекте, поэтому нужно освобождать ранее занятые ресурсы. А ещё надо обрабатывать самоприсваивание.
 
=== разница между конструктором копирования и оператором присваивания ===
=== список инициализации ===
=== исключения ===
=== RAII ===
RAII (Resource Acquisition Is Initialization) — это концепция, используемая при написании безопасного при исключениях кода. Её смысл заключается в том, что получение некоторого ресурса совмещается с инициализацией, а освобождение — с уничтожением объекта.
 
=== гарантии безопасности исключений ===
Существует три типа гарантий безопасности исключений.
 
*'''Базовая гарантия''': при возникновении любого исключения состояние программы должно оставаться согласованным.
 
*'''Строгая гарантия''': если при выполнении операции возникает исключение, то это не должно оказать какого-либо влияния на состояние приложения.
 
*'''Гарантия отсутствия исключений''': ни при каких обстоятельствах метод не будет генерировать исключения.
 
=== extern "C" ===
=== исключения в конструкторах ===
=== исключения в деструкторах ===
=== stack unwinding ===
void func( int x )
{
char* pleak = new char[1024]; // might be lost => memory leak
std::string s( "hello world" ); // will be properly destructed
if ( x ) throw std::runtime_error( "boom" );
delete [] pleak; // will only get here if x != 0
}
int main()
{
try
{
func( 10 );
}
catch ( const std::exception& e )
{
return 1;
}
return 0;
}
Here memory allocated for pleak will be lost if exception is thrown, while memory allocated to s will be properly released by std::string destructor in any case. The objects allocated on the stack are "unwound" when the scope is exited (here the scope is of the function func.) This is done by the compiler inserting calls to destructors of automatic (stack) variables.
 
=== возврат объектов из функции по значению, RVO ===
=== передача аргументов по значению, r-value/l-value ===
=== 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. int * p = static_cast<int*>(malloc(100));Если приведение не удалось, возникнет ошибка на этапе компиляции. Однако, если это приведение между указателями на объекты классов вниз по иерархии и оно не удалось, результат операции 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
правок

Навигация