205 lines
3.9 KiB
Markdown
205 lines
3.9 KiB
Markdown
#
|
|
|
|
## Про оптимизации
|
|
|
|
```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
|
|
}
|
|
```
|