C++类开发第四篇(讲清楚重载运算符怎么用)
operator运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
在c++中,可以定义一个处理类的新运算符。这种定义很像一个普通的函数定义,只是函数的名字由关键字operator及其紧跟的运算符组成。差别仅此而已。它像任何其他函数一样也是一个函数,当编译器遇到适当的模式时,就会调用这个函数。
定义重载的运算符就像定义函数,只是该函数的名字是operator@,这里的@代表了被重载的运算符。函数的参数中参数个数取决于两个因素。
[*]运算符是一元(一个参数)的还是二元(两个参数);
[*]运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数-此时该类的对象用作左耳参数)
可以重载的运算符
运算符类型运算符算术运算符加法运算符(+) 减法运算符(-) 乘法运算符(*) 除法运算符(/) 取模运算符(%)关系运算符相等运算符(==) 不等运算符(!=) 大于运算符(>) 小于运算符(=) 小于等于运算符()数组访问下标运算符([])函数调用函数调用运算符(())类型转换类型转换运算符并非所有的运算符都可以重载,例如:点运算符(.)、域解析运算符(::)、作用域运算符(::)等不能被重载。https://img2023.cnblogs.com/blog/2862884/202402/2862884-20240227175144949-1833774153.png
示例
通过一个对于加法的重载来计算时间的相加。
#ifndef TIME1_H_
#define TIME1_H_
class Time {
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHours(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time& t) const;/*在函数的末尾加上 const 表示这是一个常成员函数,即在函数内部不允许修改对象的成员变量。,参数添加const表示函数内部不会更改t对象*/
void Show() const;
};
#endif 参数是引用,但是返回类型不是引用,目的是提高效率,速度更快,使用的内存更少。
返回值不可以是引用,因为函数会创建一个新的Time对象来表示其他两个Time对象的和,返回对象会创建对象的副本,而调用函数可以使用它。如果返回类型是Time&,则引用的是重载符是局部变量,在函数结束时会被删除,因此引用会指向一个不存在的对象。
#include<iostream>
using namespace std;
#include "time1.h"
Time::Time() {
hours = minutes = 0;
}
Time::Time(int h, int m) {
hours = h;
this->minutes = m;
}
void Time::AddMin(int m) {
minutes += m;
hours += minutes / 60;
minutes %= 60;
}
void Time::AddHours(int h) {
hours += h;
}
void Time::Reset(int m, int h) {
hours = h;
minutes = m;
}
Time Time::operator+(const Time& t) const {
Time sum;
sum.minutes = minutes + t.minutes;
sum.hours = hours + t.hours +sum.hours/60;
sum.minutes %= 60;
return sum;
}
void Time::Show() const {
cout << hours << "hours, " << minutes << "mins" << endl;
}这样的话就完成了一次深拷贝,并且regina和ivanlee有各自的存储空间,修改任何一方不会影响另一方。
https://img2023.cnblogs.com/blog/2862884/202402/2862884-20240227175142337-1049435457.png
不能使用&&和||
不能重载operator&& 和 operator|| 的原因是,无法在这两种情况下实现内置操作符的完整语义。说得更具体一些,内置版本版本特殊之处在于:内置版本的&&和||首先计算左边的表达式,如果这完全能够决定结果,就无需计算右边的表达式了--而且能够保证不需要。我们都已经习惯这种方便的特性了。
我们说操作符重载其实是另一种形式的函数调用而已,对于函数调用总是在函数执行之前对所有参数进行求值。
重载遇上友元函数
重载和友元函数结合的意义在于通过友元函数的方式,实现对类的私有成员的访问,并且可以根据需要对不同版本的友元函数进行重载。这样可以灵活地扩展类的功能,并且保持良好的封装性。
具体来说,结合重载和友元函数可以实现以下几点意义:
[*]访问私有成员:通过友元函数,可以在函数体外部访问类的私有成员,而不破坏类的封装性。这在某些情况下是非常有用的,例如需要在函数外部对私有数据进行操作或显示。
[*]灵活性:重载友元函数可以根据不同的参数类型或数量实现不同的功能。这种灵活性可以让你根据具体需求选择合适的友元函数版本,从而更好地满足不同的使用场景。
[*]代码复用:通过重载友元函数,可以避免在不同情况下写多个类似的友元函数,提高代码的重用性和可维护性。
[*]简化接口:将一些与类相关的操作定义为友元函数,可以简化类的接口,使得类的使用更加直观和方便。
总的来说,重载和友元函数结合使用可以带来更大的灵活性、可读性和可维护性,同时也能够更好地平衡封装性和功能扩展性。因此,在设计类的时候,可以考虑使用友元函数来扩展类的功能,并根据需要进行重载以实现更丰富的功能。
class Time {private: int hours; int minutes; /*Myclass* ptr; Myclass* pptr;*/public: friend void display(const Time& t);};void display(const Time& t);------------ # mytime.cpp void display(const Time& t) { cout
页:
[1]