从C开始的CPP学习生活02-operator

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;
}

从C开始的CPP学习生活02-operator
http://example.com/2022/10/26/cppnote02/
作者
Anhongzhan
发布于
2022年10月26日
许可协议