# ## Про оптимизации ```cpp A obj = A(10); // A(const A&) obj1 = obj; // A(A&) ``` при отключении оптимизации будет: - преобразования - копирования - деструктор На экзе во всех задачах _вероятно_ отключена оптимизация ```cpp A f(...) { A local; return local; } ``` будет создаваться 2 переменные. ## Перегрузка (продолжение) ### Приведение типов ```cpp operator double() { return re; } double x = 3.1, y; y = C1 + x; // !error - не понятно, к какому типу y = double(C1) + x == C1 + C(x); ``` ### Ввод/вывод ```cpp friend ostream & operator<<(ostream &os, C&a) { os << "re=" << a.re << ...; return os; } int main() { C obj(1,2); cout << obj; // ostream and class return 0; } ``` ### Перегрузка вызова функции ```cpp struct Pred { bool operator()(int v) { return v < 10; } }; void f(int *mas, int n, Pred(c)) { for (int i = 0; i < n; ++i) { if (c(mas[i])) { mas[i] *= 2; } } } ``` --- ## Перегрузка функций Алгоритм для поиска наиболее подходящей функции для вызова 1. по количеству параметров 2. отбросить недопустимые преобразования 3. точные совпадения (на typedef): 1. T <-> T& 2. T[] <-> \*T 3. T -> const T 4. можно расширить тип (например к инт): 1. unsigned char 2. unsigned short 3. short and etc 4. float -> double (нет лонг дабл) 5. стандартные преобразования - Любой числовой приводится к любому числовому типу - Любой указатель приводится к указателю на void - 0 к любому указателю или любому числовому 6. пользовательсткие преобразования --- ```cpp const int ci = 1; void f(int y) {...} f(ci); // всё ок ``` --- алгоритм (фактически): - отбрасываем неподходящие - по каждому параметру берём множество подходящих функций - смотрим персечение ```cpp struct A { operator int() { return 1; } void f(double d, char c); // 1 void f(double d, int j); // 2 void f(A a, const char *p); // 3 void f(int i, const char *p); // 4 }; int main() { A a; f(a, 0); // 3 & 2 => 0 f(a, 'a'); // 12 & 1 => 1 f('a', 0); // 4 & 2 => 0 } ``` ## Статические члены класса ```cpp class A { int a; static int b; public: A(int x) : a(x) { } static void f() { cout << b; } }; int main() { int A::b = 77; A::f(); return 0; } ``` требования: - работа только с статик полями - вызывать только статик функции - нельзя как const или virtual объявить (void f const { } // может менять статик и mutable поля) ```cpp class A { static int x; int y; public: int f(int x) const {}; }; int main() { const A a; a.x = 3; cout << a.y << a.x << a.f(1); } ``` --- ```cpp struct A { int n; int k; A (A &a) { n = a.n; } int f() { return k; } A (int a) { n = a; } }; int main() { A a = A(1), b; cout << A::f() << " " << a.k << a.n << endl; // 5 53 } ``` ```cpp struct A { int n; static int k; A (const A &a) { n = a.n; } static int f() { return k; } A (int a = 3) { n = a; } }; int A::k = 5; int main() { A a = A(1), b; cout << A::f() << " " << a.k << b.n << endl; // 5 53 } ```