C++ 一元运算符重载
外观
C++一元运算符重载[编辑 | 编辑源代码]
一元运算符是仅作用于单个操作数的运算符。在C++中,可以通过运算符重载来为用户自定义类型(如类或结构体)定义这些运算符的行为。本篇文章将详细介绍如何在C++中重载一元运算符。
介绍[编辑 | 编辑源代码]
一元运算符重载允许程序员为自定义类型定义运算符的行为。常见的一元运算符包括:
- 递增(++)和递减(--)
- 正号(+)和负号(-)
- 逻辑非(!)
- 按位取反(~)
- 取地址(&)和解引用(*)
重载一元运算符可以通过成员函数或非成员函数(通常是友元函数)实现。成员函数形式更为常见,因为它能直接访问类的私有成员。
语法[编辑 | 编辑源代码]
一元运算符重载的通用语法如下:
- 成员函数形式:
返回类型 operator运算符符号() {
// 实现
}
- 非成员函数形式:
返回类型 operator运算符符号(参数类型) {
// 实现
}
示例:重载递增运算符[编辑 | 编辑源代码]
下面是一个重载前缀和后缀递增运算符的示例:
#include <iostream>
class Counter {
private:
int count;
public:
Counter(int c = 0) : count(c) {}
// 前缀++重载(成员函数)
Counter& operator++() {
++count;
return *this;
}
// 后缀++重载(成员函数)
Counter operator++(int) {
Counter temp = *this;
++count;
return temp;
}
void display() const {
std::cout << "Count: " << count << std::endl;
}
};
int main() {
Counter c1(5);
// 前缀++
++c1;
c1.display(); // 输出: Count: 6
// 后缀++
Counter c2 = c1++;
c1.display(); // 输出: Count: 7
c2.display(); // 输出: Count: 6
return 0;
}
示例:重载负号运算符[编辑 | 编辑源代码]
下面展示如何重载负号运算符:
#include <iostream>
class Distance {
private:
int meters;
public:
Distance(int m = 0) : meters(m) {}
// 重载负号运算符
Distance operator-() const {
return Distance(-meters);
}
void display() const {
std::cout << "Distance: " << meters << "m" << std::endl;
}
};
int main() {
Distance d1(10);
Distance d2 = -d1;
d1.display(); // 输出: Distance: 10m
d2.display(); // 输出: Distance: -10m
return 0;
}
成员函数 vs 非成员函数[编辑 | 编辑源代码]
下表比较了两种重载方式的区别:
实际应用案例[编辑 | 编辑源代码]
考虑一个表示复数的类,我们可以重载一元运算符来实现各种操作:
#include <iostream>
#include <cmath>
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 重载正号运算符(通常返回副本)
Complex operator+() const {
return *this;
}
// 重载负号运算符
Complex operator-() const {
return Complex(-real, -imag);
}
// 重载逻辑非运算符(判断是否为零)
bool operator!() const {
return (real == 0) && (imag == 0);
}
void display() const {
std::cout << real << (imag >= 0 ? "+" : "") << imag << "i" << std::endl;
}
};
int main() {
Complex c1(3, 4);
Complex c2 = -c1;
c1.display(); // 输出: 3+4i
c2.display(); // 输出: -3-4i
if (!Complex(0, 0)) {
std::cout << "Zero complex number" << std::endl;
}
return 0;
}
注意事项[编辑 | 编辑源代码]
1. 不能创建新的运算符,只能重载现有的C++运算符 2. 不能改变运算符的优先级和结合性 3. 某些运算符(如?:、::、.、.*等)不能被重载 4. 重载运算符时,至少有一个操作数必须是用户定义类型 5. 保持运算符的直观含义,避免令人困惑的实现
数学表示[编辑 | 编辑源代码]
对于复数类的负号运算符重载,可以用数学表示为:
其中是实部,是虚部。
总结[编辑 | 编辑源代码]
一元运算符重载是C++中强大的特性,允许自定义类型像内置类型一样使用运算符。通过合理使用运算符重载,可以使代码更直观、更易读。记住要保持运算符的语义清晰,并遵循运算符重载的最佳实践。