首先,阅读之前要先搞清楚什么是运算符、函数重载。函数重载就是在一个范围内为一个函数声明多个实现方式,函数名必须一致。
那么C++运算符是否可以重载呢?可以!先弄清什么时候需要进行运算符重载:
假设,你有一个类或者结构体,想通过 +、-、*、/ 这种最基本的运算符直接进行计算,又或者想用 ==、|| 直接进行比较。
这时候运算符重载的作用就来了。
C++当中的运算符重载是通过 operator 关键字来实现的,当你定义了类或结构体后,编译器肯定无法智能地对类本身进行运算及比较。
因此,需要根据实际需要进行运算符的重载。
下面一段代码是在一个类中对 = 进行了一个最简单的重载:
void operator=(const DataPack &in) {
this->name = in.name;
this->value = in.value;
};
可以看到,运算符重载也是一个简单的函数,它也有返回值类型、参数。
只不过它的函数名被强制要求为了【operator 关键字 + 要重载的运算符】。
运算符重载的目的,就是为了实现自定义数据类型对运算符作用的支持。
既然重载了运算符,那么返回值与参数必须与运算符本意相匹配,否则编译器会报错:
【正确】
bool operator==(const DataPack &in) {
return this->value == in.value;
};
【错误】
void operator>=(const DataPack &in) {
};
重载运算符的函数体,就是对运算符作用的自定义实现:
DataPack operator+(const DataPack &in) {
DataPack out;
out.name = this->name;
out.value = this->value + in.value;
return out;
};
那么有哪些运算符可以重载呢?
分类 | 运算符列表 |
---|---|
双目算术运算符 | + (加),-(减),*(乘),/(除),% (取模) |
关系运算符 | ==(等于),!= (不等于),< (小于),> (大于),<=(小于等于),>=(大于等于) |
逻辑运算符 | ||(逻辑或),&&(逻辑与),!(逻辑非) |
单目运算符 | + (正),-(负),*(指针),&(取地址) |
自增自减运算符 | ++(自增),--(自减) |
位运算符 | | (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移) |
赋值运算符 | =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>= |
空间申请与释放 | new, delete, new[ ] , delete[] |
其他运算符 | ()(函数调用),->(成员访问),,(逗号),[](下标) |
不可重载的运算符:
运算符 | 说明 |
---|---|
. | 成员访问运算符 |
.* , ->* | 成员指针访问运算符 |
:: | 域运算符 |
sizeof | 长度运算符 |
? | 条件运算符 |
# | 预处理符号 |
部分可重载的运算符演示:
class DataPack {
public:
DataPack() {};
DataPack(const string &n, int v) : name(n), value(v) {};
/* --- 算术运算符重载 --- */
DataPack operator+(const DataPack &in) {
DataPack out;
out.name = this->name;
out.value = this->value + in.value;
return out;
};
DataPack operator*(const DataPack& in) {
DataPack out;
out.name = this->name;
out.value = this->value * in.value;
return out;
};
/* --- 赋值运算符重载 --- */
void operator=(const DataPack &in) {
this->name = in.name;
this->value = in.value;
};
void operator+=(const DataPack &in) {
this->value += in.value;
};
/* --- 关系运算符重载 --- */
bool operator==(const DataPack &in) {
return this->value == in.value;
};
bool operator>=(const DataPack &in) {
return this->value >= in.value;
};
/* --- 逻辑运算符重载 --- */
bool operator&&(const DataPack& in) {
return this->value == in.value;
};
bool operator!() {
return this->value <= 0;
};
/* --- 自增减运算符重载 --- */
void operator++() {
this->value += 1;
};
void operator--() {
this->value -= 1;
};
/* ---位运算符重载--- */
bool operator&(const DataPack& in) {
return this->value = in.value;
}
/* ---输入输出运算符重载--- */
friend std::istream& operator>>(std::istream& in, DataPack& th) {
in >> th.name >> th.value;
return in;
}
friend std::ostream& operator<<(std::ostream& out, const DataPack& th) {
out << th.name << th.value;
return out;
}
private:
string name;
int value = 0;
};
除此之外,可以将运算符重载声明到类外部作为全局函数,便可以进行全局重载:
class DataPack {
public:
DataPack() {};
DataPack(const string &n, int v) : name(n), value(v) {};
public:
string name;
int value = 0;
};
DataPack operator+(const DataPack& a, const DataPack& b) {
DataPack out;
out.name = a.name;
out.value = a.value + b.value;
return out;
};
但请注意,以下运算符只能作为成员函数进行重载:
运算符 | 说明 |
---|---|
() | 函数调用 |
[] | 取下标 |
-> | 成员访问 |
= | 赋值 |
1,重载运算符并不会改变运算符自身的优先级与结合性。
2,重载运算符并不会改变它的原有用法。
3,运算符重载函数不能有默认参数。
====================================
芯片烤电池 C++ Example 2022-Spring Season Pass :
【Example】C++ 回调函数及 std::function 与 std::bind
【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr
【Example】C++ Template (模板)概念讲解及编译避坑
【Example】C++ 标准库 std::thread 与 std::mutex
【Example】C++ 标准库多线程同步及数据共享 (std::future 与 std::promise)
【Example】C++ 标准库 std::condition_variable
【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)
【Example】C++ 单例模式 演示代码 (被动模式、兼容VS2022编译)
====================================
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。