Изменения

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

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

15 198 байт добавлено, 23:39, 9 марта 2013
перегрузка операторов, ADL
=== классы ===
Класс — пользовательский тип, объявленный с помощью '''struct''', '''class''' или '''union'''.
 
=== конструкторы ===
Конструктор вызывается при создании объекта для его инициализации. Обозначается как одноимённая классу функция, не имеющая типа возвращаемого значения. Класс может иметь сколько угодно конструкторов с разными наборами параметров. Конструктор без параметров (или все аргументы которого имеют параметры по умолчанию) называется ''конструктором по умолчанию'', а конструктор с первым параметром-ссылкой на тот же класс — ''конструктором копирования''.
 
Array a(5); // вызывается Array::Array(int)
Array b; // вызывается Array::Array()
Array c(a); // вызывается Array::Array(const Array&)
Array d=a; // вызывается Array::Array(const Array&)
b=c; // происходит вызов оператора =
 
Если в классе нет явно объявленных конструкторов, то он имеет неявно объявленный конструктор без параметров, который конструирует подобъекты классов-родителей и инициализирует поля класса с помощью конструкторов по умолчанию.
 
Конструктор копирования также неявно объявляется при отсутствии явного. Он выполняет копирование всех объявленных полей с помощью соответствующих конструкторов копирования.
 
Конструкторы не могут быть виртуальными.
 
=== деструкторы ===
Деструктор вызывается для уничтожения объекта класса. Обозначается как имя класса, перед которым ставится тильда. Деструктор не имеет типа возвращаемого значения и принимаемых аргументов. Класс может иметь только один деструктор.
 
Если деструктор не объявлен явно, то класс имеет неявно объявленный деструктор.
 
Деструктор может быть виртуальным (и обычно так и объявляется, чтобы гарантировать правильное уничтожение доступного по ссылке или указателю объекта независимо от того, какого типа ссылка или указатель).
 
=== const ===
==== Переменные ====
Очевидно, const переменные — это переменные, которые нельзя менять. Инициализируются в момент объявления.
const int p = 1; //инициализация в момент объявления, всё ок
const int q;
q = 5; //а вот так уже нельзя
==== Функции-члены класса ====
Такие функции не могут менять поля класса, не объявленные как static или mutable, не могут возвращать не const ссылки и указатели на поля класса и не могут вызывать неконстантные функции класса.
 
=== ссылки ===
=== разница между ссылками и указателями ===
[http://pastebin.com/FH9ChQUG]
 
=== l-value, r-value ===
[http://www.rsdn.ru/article/cpp/lvalue.xml]
 
=== перегрузка операторов ===
[http://habrahabr.ru/post/132014/]
 
=== оператор присваивания ===
Оператор присваивания генерируется компилятором. Генерируемый компилятором код выполняет поверхностное копирование всех полей (что может быть не очень подходящим вариантом).
 
Оператор присваивания вызывается на уже проинициализированном объекте, поэтому нужно освобождать ранее занятые ресурсы. А ещё надо обрабатывать самоприсваивание.
 
=== разница между конструктором копирования и оператором присваивания ===
=== список инициализации ===
=== порядок инициализации/разрушения полей класса ===
Поля инициализируются в том порядке, в котором они объявлены, даже если в списке инициализации они указаны в другом порядке. Разрушаются в порядке, обратном порядку объявления.
 
=== volatile ===
=== директивы препроцессора ===
=== #pragma once vs include guards ===
=== preprocessor pitfalls ===
[http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter09_001.html]
 
=== циклический экспанд макросов ===
=== циклические зависимости на хедерах ===
=== неполные типы ===
[http://msdn.microsoft.com/en-en/library/200xfxh6.aspx]
 
=== name mangling ===
=== перегрузка функций ===
=== исключения ===
=== 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
правок

Навигация