C++运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class CStu { public: int nAge; double dScore;
CStu() { nAge = 12; dScore = 16.23; } };
void operator+(CStu& st, int a) { std::cout << (st.nAge + a) << std::endl; }
int main() { CStu st1, st2; st1 + 12; return 0; }
|
通常情况下我们只能对一些基本数据类型,比如int,float.double等进行加减乘除,那么我们是否可以对对象进行加减乘除呢?
答案是不可以,我们在main中直接使用st1 + 12;编译器会报错
但并不是完全不可用,c++中存在一种叫做运算符重载的方式,可以让我们自己设定运算符的操作数的类型,这样我们就可以让类的对象进行加减乘除了
1、有返回值的运算符重载
1 2 3
| int operator+(CStu& st, int a) { return st.nAge + a; }
|
此时不可以使用12+stu1;
原因是运算符找不到对应类型的操作数
此时我们可以再增加一个运算符重载函数
1 2 3
| int operator+(int a, CStu& st) { return st.nAge + a; }
|
也可以两个类之间进行运算
1 2 3
| int operator+(CStu& st1, CStu& st2) { return st1.nAge + st2.nAge; }
|
返回值的类型也可以改变
1 2 3 4
| CStu& operator+(CStu& st1, CStu& st2) { st1.nAge += st2.nAge; return st1; }
|
2、类内重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class CStu { public: int nAge;
CStu() { nAge = 12; }
int operator+(int a) { return (nAge + a); } };
int main() { CStu stu; std::cout << stu + 12 << std::endl; return 0; }
|
可以看出,写在类内的重载在调用时和写在类外的重载是相同的。
由于类内的函数默认第一个参数是this指针,所以我们在实现运算符重载的时候可以少写入一个参数,并且,类内运算符重载只能写入一个参数,如果想要使用12 + stu;
,我们需要类外实现
3、运算符重载定义在类内还是类外
- 左操作数不是对象的,就选择类外重载运算符
- =,[],(),->必须是类内重载
- 符合复制运算符通常是类内重载 +=、<<=
- 改变对象状态的运算符,如++ –等,通常是类内重载
- 算数,关系,位运算通常是类外重载
4、运算符重载的例子
4.1、二元运算符重载
二元运算符:
- 算术运算符:+ - * / %
- 关系运算符:>= <= > < != ==
- 位运算符:^ & |
- 逻辑运算符: && ||
>=
1 2 3
| int operator >= (CStu& st1, CStu& st2) { return (st1.nAge >= st2.nAge); }
|
&&
1 2 3
| int operator && (CStu& st1, CStu& st2) { return (st1.nAge && st2.nAge); }
|
4.2、一元运算符
一元运算符: - + & * ~ ! (正 负 取地址 内存操作 按位取反 非)
-
1 2 3
| int operator-(CStu& st) { return -st.nAge; }
|
也可以写在类内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class CStu { public: int nAge;
CStu(int a) { nAge = a; }
int operator-() { return (-this->nAge); } };
|
4.3、输入输出
cout是ostream的对象,cin是istream的对象
4.3.1、ostream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class CStu { public: int nAge;
CStu() { nAge = 12; } };
std::ostream& operator << (std::ostream& os, const CStu& st) { os << st.nAge; return os; }
int main() { CStu st; std::cout << st << st;
return 0; }
|
参数一是ostream的引用,参数2是常引用
必须是类外重载
一般情况下要输出的变量是私有成员,此时可以使用友元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class CStu { private: int nAge; public: CStu() { nAge = 12; }
friend std::ostream& operator << (std::ostream& os, const CStu& st); };
std::ostream& operator << (std::ostream& os, const CStu& st) { os << st.nAge; return os; }
int main() { CStu st; std::cout << st << st;
return 0; }
|
4.3.2、istream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| class CStu { private: int nAge;
public: CStu() { nAge = 13; }
friend std::istream& operator >> (std::istream& is, CStu& stu); friend std::ostream& operator << (std::ostream& os, const CStu& st); };
std::istream& operator >> (std::istream& is, CStu& stu) { is >> stu.nAge; return is; }
std::ostream& operator << (std::ostream& os, const CStu& st) { os << st.nAge; return os; }
int main() { CStu st; std::cin >> st; std::cout << st;
return 0; }
|
4.3.3、赋值运算符
= -= += *= /=
前面提到过,**=**必须是类内重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class CStu { public: int nAge; CStu() { nAge = 16; }
void operator = (int a) { this->nAge = a; }
}; int main() { CStu st; st = 113; return 0; }
|
+=
1 2 3 4 5 6 7 8 9 10 11 12
| CStu& operator += (CStu& st, int a) { st.nAge += a; return st; }
int main() { CStu st; st += 113; return 0; }
|
4.3.4、下标运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class CStu { public: int a, b, c, d; CStu() { a = b = c = d = 1; }
int& operator[](int n) { switch (n) { case 0: return a; break; case 1: return b; break; case 3: return c; break; default: return d; } } };
int main() { CStu st; std::cout << st[1] << std::endl; st[1] = 18; std::cout << st[1]; return 0; }
|
4.3.5、自增自减运算符
左++
1 2 3
| int operator ++ (CStu& st) { return ++st.nAge; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class CStu { public: int nAge;
CStu() { nAge = 12; }
int operator ++ () { return ++nAge; } };
|
右++
1 2 3 4 5
| int operator ++ (CStu& st, int n) { n = st.nAge++; return n; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class CStu { public: int nAge;
CStu() { nAge = 12; }
int operator ++ (int n) { n = nAge++; return n; } };
|
4.3.6、重载类型转换
只能定义在类内
不能对类成员进行修改
没有返回类型
1 2 3 4 5 6 7 8 9
| operator int() const { return a; }
operator double() const { return b; }
|
1 2 3 4 5 6 7
| int main() { CStu st; std::cout << (int)st << std::endl; std::cout << (double)st << std::endl; return 0; }
|