重载运算符总结

重载运算符

一重载运算符的限制

在我们定义了类之后,出现了一些新的数据类型,因此我们要根据数据类型的不同要重新编写我们的运算符,在c++中大部分的预定义的运算符都可以被重载,但以下运算符不能被重载 "." ".*" "::" "?" "sizeof"。

重载运算符函数可以对运算符做出新的解释,即定义用户所需要的各种操作。但运算符重载后,原有的基本语句不变,包括

1 不改变运算符的优先级

2 不改变运算符的结合性

3 不改变运算符所需要的操作数

要注意的是不能创新的运算符,只有系统预定义的运算符才能被重载。

二重载运算符的语法形式

运算符函数是一种特殊的成员函数或友元函数。成员函数的语句格式为:

类型 类名::operator op(参数表)

{

//相对于该类定义的操作

}

类型是函数的返回类型。“类名”是要重载该运算符的类。“op”表示要重载的运算符“参数表”列出该运算符所需要的操作数

重载运算符的函数不能有默认参数. 
重载的运算符必须和用户定义的自定义类型一起使用,其参数至少应有一个是类对象(或类对象的引用) 
防止用户修改用于标准数据类型的运算符
用于类对象的运算符一般必须重载,但有两个例外“=”和“&”不必重载 
"=”,系统有默认的重载函数,就是逐个复制成员,除非有必要(像动态分配内存的内容)就不必重载 
"&",它能返回类对象在内存中的起始地址 
要按习惯重载,虽然可以但还是不要把“+”重载成 减法,否则有违重载的初衷 

运算符重载函数可以是类成员函数(如“+”左边必须是类),类友元函数(需要访问类私有成员时使用很方便),普通函数(访问类私有成员时不太方便) 

重载运算符有两种方式

一种是成员函数重载运算符,另一种是友元函数重载运算符。

重载为类的成员函数

返回类型(类名::)operator运算符(形参表){函数体;}

重载为类的友元函数

friend 函数类型 operator 运算符(形参表){函数体;}

通过友元关系可以实现不同类或对象的成员函数之间,类的成员函数与一般函数之间进行数据共享机制。我们先在类中声明这几个重载函数为该类的友元,这里要注意此时重载函数的参数有两个而不是一个,友元函数需要两个参数分别调用在主函数往里面传递的值,友元函数最大的好处就是能够调用类中的私有数据成员,还能保证类的封装性。所以我认为一般用友元函数重载运算符要比用成员函数重载要好用。

  1. #include <iostream>  
  2. using namespace std;  
  3. class Coordinate  
  4. {  
  5. public:  
  6.     Coordinate(int x, int y)  
  7.     {  
  8.         m_iX = x;  
  9.         m_iY = y;  
  10.     }  
  11.     Coordinate &operator--()  
  12.     {  
  13.         this->m_iX--;  
  14.         this->m_iY--;  
  15.         return *this;  
  16.     }  
  17.     Coordinate operator--(int)  
  18.     {  
  19.         Coordinate coor(*this);  
  20.         coor.m_iX=this->m_iX--;  
  21.         coor.m_iY=this->m_iY--;  
  22.         return coor;  
  23.     }  
  24.     Coordinate operator+(Coordinate &c)  
  25.     {  
  26.         Coordinate temp(0,0);  
  27.         temp.m_iX=this->m_iX+c.m_iX;  
  28.         temp.m_iY=this->m_iY+c.m_iY;  
  29.         return temp;  
  30.     }  
  31. public:  
  32.     int m_iX;  
  33.     int m_iY;  
  34. };  
  35.   
  36. int main(void)  
  37. {  
  38.     Coordinate coor1(1, 3);  
  39.     Coordinate coor2(2, 4);  
  40.     Coordinate coor3(0, 0);  
  41.   
  42.     coor1--;  
  43.     --coor2;  
  44.     coor3 = coor1 + coor2;  
  45.   
  46.     cout << coor3.m_iX << endl;  
  47.     cout << coor3.m_iY << endl;  
  48.   
  49.     return 0;  
  50. }  

<think>好的,我现在需要帮助用户了解在ACM编程竞赛中运算符重载的实现与用法。首先,我需要整理用户提供的引用内容,看看有哪些相关的信息可以参考。 用户提到的引用1和2都提到了复数类的运算符重载,特别是重载+、*和<<运算符。引用2还提到了两种重载方式:类成员函数和全局函数,并且需要友元声明。引用3提到了实验题目,可能涉及具体的实现细节。引用4是关于时间日期类的运算符重载,比如加减运算,这可能与ACM中的实际问题相关。 首先,我应该解释运算符重载的基本概念,说明它在ACM中的作用,比如简化代码,提高可读性。然后,结合用户提供的例子,复数类和时间类,分别展示如何实现常见的运算符重载,比如加减、比较、输入输出等。 接下来,需要区分类成员运算符重载和全局函数重载同之处,比如参数数量,是否需要友元等。例如,成员函数的运算符重载,比如operator+,只需要一个参数,因为左操作数是this指针;而全局函数需要两个参数。 然后,在ACM中,常见的应用场景可能包括复数运算、大数运算、矩阵运算、几何计算等,这些都需要重载运算符来简化操作。需要举几个例子,比如矩阵加法或向量的叉乘,用运算符重载如何实现。 另外,注意事项也很重要,比如重载运算符(如::、.、.*等),以及运算符的优先级和结合性保持变。同时,友元函数的使用场景,比如当左操作数是当前类的对象时,必须使用全局函数重载,比如<<运算符。 最后,总结在ACM中使用运算符重载的好处,比如代码简洁、减少错误,并提醒用户注意合理使用,避免过度复杂化。 现在需要确保回答符合用户的要求,结构清晰,分点说明,并包含相关示例代码,比如复数类的+和<<重载,时间类的加减运算。同时,生成相关问题,帮助用户进一步学习。</think>### ACM竞赛中运算符重载的实现与用法 在ACM编程竞赛中,运算符重载(Operator Overloading)是C++中一项重要特性,能够通过自定义类对象的行为,使代码更简洁高效。以下从实现方法和典型应用场景展开说明。 --- #### 一、运算符重载的实现方法 运算符重载分为**类成员函数重载**和**全局函数重载**两种形式,具体选择取决于操作符的语义需求。 1. **类成员函数重载** 运算符作为类的成员函数时,左操作数为当前类的对象(`this`指针),右操作数为参数。 **示例(复数加法)**: ```cpp class Complex { public: Complex(double r = 0, double i = 0) : real(r), imag(i) {} // 成员函数重载 "+" Complex operator+(const Complex& other) { return Complex(real + other.real, imag + other.imag); } private: double real, imag; }; ``` 2. **全局函数重载(需友元声明)** 当左操作数是当前类对象时(如输入输出流`<<`),需声明为全局函数并配合`friend`关键字。 **示例(复数输出)**: ```cpp class Complex { friend ostream& operator<<(ostream& os, const Complex& c); // 声明友元 }; // 全局重载 "<<" ostream& operator<<(ostream& os, const Complex& c) { os << c.real << "+" << c.imag << "i"; return os; } ``` --- #### 二、ACM中的典型应用场景 1. **复数运算** 直接通过`+`、`*`等运算符实现复数加减乘除,避免手动拆解实虚部。 **乘法重载示例**: ```cpp Complex operator*(const Complex& a, const Complex& b) { return Complex(a.real*b.real - a.imag*b.imag, a.real*b.imag + a.imag*b.real); } ``` 2. **时间/日期计算** 实现时间的加减或比较操作,例如计算时间差[^4]。 **时间加法示例**: ```cpp class Time { public: Time operator+(int seconds) { Time result = *this; result.sec += seconds; // 处理进位逻辑 return result; } }; ``` 3. **几何计算** 向量点乘、叉乘等操作可通过运算符简化: ```cpp Vector3D operator*(const Vector3D& v1, const Vector3D& v2) { return Vector3D(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); // 叉乘 } ``` --- #### 三、注意事项 1. **重载运算符** `::`、`.`、`.*`、`sizeof`等运算符重载。 2. **保持语义一致性** 例如重载`+`应修改操作数本身,而是返回新对象。 3. **优先选择成员函数** 对称运算符(如`+`、`==`)可灵活选择,但输入输出流必须全局重载。 --- #### 四、优势总结 - **代码简洁性**:直接通过`a + b`代替`a.add(b)`。 - **可读性提升**:运算符语义直观,如`vector1 * vector2`表示叉乘。 - **减少错误**:封装底层操作,避免重复代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值