## Мини-отступление ```cpp #include C f() { C local var; // return local_var - криво return std::move(local_var) } ``` Благодаря std::move можно не создавать вторую переменную для возвращаемого значения. Входит в стандарт с c++17 и оптимизируется автоматически в c++14. --- # Перегрузка операций ## Дружеские функции ```cpp class C { int a; public: ... friend void f(C &x); }; void f(C &x) {cout << x.a} ``` функция также может относиться к другому классу ## Перегргузка операций Нельзя перегружать: - \# - :: - ?: - . - .\* - sizeof - typeid ### Бинарные операции ```cpp class C{ double re; double im; public: C (double x = 0.0, double y = 0.0) : re(x), im(y) {} bool isEqual(C &obj) { return re == obj.re && im == obj.im; // неявная подстановка this-> } bool operator ==(C &obj) { return re == obj.re && im == obj.im; } // нужен const, чтобы можно было делать o3 = o1 + 10.0 C operator+(const C& obj) { return C(re + obj.re, im + obj.im); } // o3 = o1 + o2 }; void main() { C o1, o2, o3; o1.isEqual(o2) == (o1 == o2); // the same o3 = o1 + o2; o3 = o1 + 10.0 } ``` либо для дальнейшей работы и `o1 = 10.0 + o2` изменим перегрузку операнда: ```cpp friend C operator+(const C& obj1, const C& obj2) { return C(obj2.re + obj1.re, obj2.im + obj1.im); } ``` ### Унарные операции ```cpp C operator-() { return C(-re, -im); } // o3 = -o1 // !! не перегрузит никак бинарную ``` Посткремент и инкремент: ```cpp C& operator++() { re++; im++; return *this; } C operator++(int NU) { // not used var С tmp(re, im); re++; im++; return tmp; } void main() { o3 = ++o1; o3 = o1++; } ``` `o3 = (o1++)++;` не проработает!! (изменит временную переменную) ### Перегрузка =, [], () > не перегружаются как дружественные! ```cpp C &operator=(const C &obj) { re = obj.re; im = obj.im; return *this; } // по умолчанию так перегружается ``` ## Итоговый пример ```cpp int main() { string s1("abcd"), s2("qw"), s3; s2[1] = 'A'; s2.print(); s3 = s1 + s2; s3.print(); } ``` Итоговый код, чтобы условие выше выполнялось: ```cpp #include #include #include #include class string { int len; // количество памяти char* str; public: string(const char* s = "") { len = strlen(s) + 1; str = new char[len]; strcpy(str, s); } char& operator[](int n) { return str[n]; } string operator+(string s) { string tmp; tmp.len = s.len + len - 1; tmp.str = new char[tmp.len]; strcpy(tmp.str, str); strcpy(tmp.str + len - 1, s.str); return tmp; } string operator=(string s) { if (s.str == str) { return s; } delete[] str; len = s.len; str = new char[len]; strcpy(str, s.str); return *this; } // ~string() { delete[] str; } почему-то с ним не работает (?) void print() { std::cout << str << " " << len << std::endl; } }; ``` версия присваивания получше: ```cpp void string::swap(string& a) { std::swap(str, a.str); std::swap(len, a.len); } string& string::operator=(string a) { swap(a); return *this; } ```