您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++中operator关键字如何使用
## 1. 运算符重载概述
运算符重载是C++中一项强大的特性,它允许程序员为自定义类型定义运算符的行为。通过使用`operator`关键字,我们可以使自定义类型的对象能够像内置类型一样使用各种运算符,从而使代码更加直观和易读。
### 1.1 运算符重载的基本概念
运算符重载本质上是一种特殊的函数,它定义了特定运算符在作用于类对象时的行为。重载的运算符仍然保持其原有的优先级和结合性。
### 1.2 可重载的运算符
C++中大多数运算符都可以被重载,包括:
- 算术运算符:`+`, `-`, `*`, `/`, `%`
- 关系运算符:`==`, `!=`, `<`, `>`, `<=`, `>=`
- 逻辑运算符:`&&`, `||`, `!`
- 位运算符:`&`, `|`, `^`, `~`, `<<`, `>>`
- 赋值运算符:`=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `<<=`, `>>=`
- 其他运算符:`[]`, `()`, `->`, `,`, `new`, `delete`, `new[]`, `delete[]`
不可重载的运算符包括:
- 成员访问运算符:`.`
- 成员指针访问运算符:`.*`
- 作用域解析运算符:`::`
- 条件运算符:`?:`
- `sizeof`运算符
## 2. 运算符重载的基本语法
运算符重载可以通过成员函数或非成员函数(通常是友元函数)来实现。
### 2.1 成员函数形式
```cpp
class MyClass {
public:
// 一元运算符
ReturnType operatorOp() {
// 实现代码
}
// 二元运算符
ReturnType operatorOp(const MyClass& rhs) {
// 实现代码
}
};
class MyClass {
friend ReturnType operatorOp(const MyClass& lhs, const MyClass& rhs);
};
ReturnType operatorOp(const MyClass& lhs, const MyClass& rhs) {
// 实现代码
}
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 成员函数形式重载+
Complex operator+(const Complex& rhs) const {
return Complex(real + rhs.real, imag + rhs.imag);
}
// 友元函数形式重载-
friend Complex operator-(const Complex& lhs, const Complex& rhs) {
return Complex(lhs.real - rhs.real, lhs.imag - rhs.imag);
}
};
class Person {
private:
std::string name;
int age;
public:
// 重载==运算符
bool operator==(const Person& rhs) const {
return name == rhs.name && age == rhs.age;
}
// 重载<运算符用于排序
bool operator<(const Person& rhs) const {
if (name != rhs.name)
return name < rhs.name;
return age < rhs.age;
}
};
class Date {
private:
int day, month, year;
public:
// 重载<<运算符
friend std::ostream& operator<<(std::ostream& os, const Date& dt) {
os << dt.day << '/' << dt.month << '/' << dt.year;
return os;
}
// 重载>>运算符
friend std::istream& operator>>(std::istream& is, Date& dt) {
char sep;
is >> dt.day >> sep >> dt.month >> sep >> dt.year;
return is;
}
};
class IntArray {
private:
int* data;
size_t size;
public:
IntArray(size_t s) : size(s), data(new int[s]) {}
~IntArray() { delete[] data; }
// 重载[]运算符
int& operator[](size_t index) {
if (index >= size)
throw std::out_of_range("Index out of range");
return data[index];
}
// const版本的重载
const int& operator[](size_t index) const {
if (index >= size)
throw std::out_of_range("Index out of range");
return data[index];
}
};
class Adder {
private:
int value;
public:
Adder(int v) : value(v) {}
// 重载()运算符
int operator()(int x) const {
return value + x;
}
};
// 使用示例
Adder add5(5);
int result = add5(10); // 结果为15
class MyNumber {
private:
int value;
public:
MyNumber(int v) : value(v) {}
// 转换为int类型
operator int() const {
return value;
}
// 转换为double类型
operator double() const {
return static_cast<double>(value);
}
};
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;
}
};
class MemoryDemo {
public:
// 重载new运算符
static void* operator new(size_t size) {
std::cout << "Custom new for size " << size << std::endl;
return ::operator new(size);
}
// 重载delete运算符
static void operator delete(void* ptr) noexcept {
std::cout << "Custom delete" << std::endl;
::operator delete(ptr);
}
// 重载new[]运算符
static void* operator new[](size_t size) {
std::cout << "Custom new[] for size " << size << std::endl;
return ::operator new[](size);
}
// 重载delete[]运算符
static void operator delete[](void* ptr) noexcept {
std::cout << "Custom delete[]" << std::endl;
::operator delete[](ptr);
}
};
运算符重载应该保持其原有的语义。例如,+
运算符应该执行某种形式的加法操作,而不是执行减法或其他不相关的操作。
对于二元运算符,如果左操作数不是类的对象,则需要使用非成员函数形式重载。例如,要实现5 + obj
这样的表达式,运算符必须是非成员函数。
在重载赋值运算符时,需要考虑自赋值的情况:
class MyString {
private:
char* str;
public:
MyString& operator=(const MyString& rhs) {
if (this == &rhs) // 检查自赋值
return *this;
delete[] str;
str = new char[strlen(rhs.str) + 1];
strcpy(str, rhs.str);
return *this;
}
};
对于返回新对象的运算符(如+
),应该直接返回对象而不是指针或引用:
Complex operator+(const Complex& lhs, const Complex& rhs) {
return Complex(lhs.real + rhs.real, lhs.imag + rhs.imag);
}
C++11引入了移动语义,可以优化运算符重载的性能:
class MyString {
public:
// 移动赋值运算符
MyString& operator=(MyString&& rhs) noexcept {
if (this != &rhs) {
delete[] str;
str = rhs.str;
rhs.str = nullptr;
}
return *this;
}
};
C++20引入了<=>
三路比较运算符:
class Point {
private:
int x, y;
public:
auto operator<=>(const Point&) const = default;
};
class Distance {
private:
double meters;
public:
Distance(double m) : meters(m) {}
// 定义_km字面量运算符
friend Distance operator"" _km(long double val) {
return Distance(val * 1000);
}
};
// 使用示例
auto d = 5.5_km; // 创建5500米的Distance对象
运算符重载是C++中一项强大的特性,它允许我们为自定义类型定义直观的操作方式。通过合理使用operator
关键字,我们可以:
然而,运算符重载也需要谨慎使用,遵循以下原则:
通过掌握运算符重载的各种技巧和最佳实践,C++程序员可以编写出更加优雅和高效的代码。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。