3.9 KiB
3.9 KiB
Мини-отступление
#include <utility>
C f() {
C local var;
// return local_var - криво
return std::move(local_var)
}
Благодаря std::move можно не создавать вторую переменную для возвращаемого значения. Входит в стандарт с c++17 и оптимизируется автоматически в c++14.
Перегрузка операций
Дружеские функции
class C {
int a;
public:
...
friend void f(C &x);
};
void f(C &x) {cout << x.a}
функция также может относиться к другому классу
Перегргузка операций
Нельзя перегружать:
- #
- ::
- ?:
- .
- .*
- sizeof
- typeid
Бинарные операции
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 изменим перегрузку операнда:
friend C operator+(const C& obj1, const C& obj2) {
return C(obj2.re + obj1.re, obj2.im + obj1.im);
}
Унарные операции
C operator-() {
return C(-re, -im);
} // o3 = -o1
// !! не перегрузит никак бинарную
Посткремент и инкремент:
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++)++; не проработает!! (изменит временную переменную)
Перегрузка =, [], ()
не перегружаются как дружественные!
C &operator=(const C &obj) {
re = obj.re;
im = obj.im;
return *this;
} // по умолчанию так перегружается
Итоговый пример
int
main() {
string s1("abcd"), s2("qw"), s3;
s2[1] = 'A';
s2.print();
s3 = s1 + s2;
s3.print();
}
Итоговый код, чтобы условие выше выполнялось:
#include <string.h>
#include <cstring>
#include <utility>
#include <iostream>
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;
}
};
версия присваивания получше:
void string::swap(string& a) {
std::swap(str, a.str);
std::swap(len, a.len);
}
string& string::operator=(string a) {
swap(a);
return *this;
}