【C++】 类与对象(二)(2.运算符重载)
发布时间:2026/9/28 3:40:54来源:尧图网络
目录赋值运算符重载1.运算符重载2.赋值运算符重载3.日期类实现取地址运算符重载1.const 成员2.取地址运算符重载运算符重构operator运算符重构是对类这和算符的适配性进行一个适配的重构就是对于平常的运算符无法进行加减乘除等等还有赋值操作符进行一个新的从新修改。而在C中就允许我们可以进行对运算符进行从新修改操作对于运算符重构还需要有一个重要字operator在这个关键字的后面直接加上对应的运算符像 -- -等等除了.* :: sizeo() . ?:)这5个运算符无法修改。赋值运算符重载1.运算符重载运算符重载的注意点1必须是有一个类相关的传值如果没有就变成重构原本的运算的意义//error int operator(int a,int b) { return a-b; }2不能重构没有意义的运算符如operator加减运算符重载正确示范以 Date 日期类为例日期类的运算符重载实现/*传年月取月份总天数*/ int Date::GetMonthDay(int year, int month) { //最基础的实现一一对应每个月份的数组传值为了不浪费一个空间把0位置改为闰年2月份的存储位置 static const int month_day[13] { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; //2月份 闰年的判断 if (month 2 ((year % 4 0 year % 100 ! 0) || year % 400 0)) { return 29; } else { return month_day[month]; } } Date Date::operator(int day) { //判断如果传过来的day 是否为负数如果为负数就给-处理注意一定要改day的正负数 if (day 0) { return *this - -day; } //先进行加减 _day day; //修改直到day为正确的日期为止 注意不要号会导致出现0号情况 while (_day GetMonthDay(_year, _month)) { _day - GetMonthDay(_year, _month); if (_month 13) { _month 1; _year; } } return *this; }注意对应的*this 在函数销毁时*this 的生命周期还在所以可以用类类型的应用进行返回。日期类的运算符重载实现//利用已有的实现 Date Date::operator(int day) { // 的实现是通过原数值没有更改 所以进行拷贝出来的实例化对象用这个实例化对象进行操作 Date tmp *this; return tmp day; } 的实现是通过原数值没有更改 所以进行拷贝出来的实例化对象用这个实例化对象进行操作注意所拷贝出来的对象是一个临时对象这个不能用Date 的类类型的引用返回值只能用类类型即可。日期类的- -运算符重载实现与 是同理的Date Date::operator-(int day) { //判断如果传过来的day 是否为负数如果为负数就给处理注意一定要改day的正负数 if (day 0) { return *this -day; } //先进行加减 _day - day; //修改直到day为正确的日期为止 注意这里与不同需要0,还是那个问题防止出现0号的问题 while (_day 0) { _day GetMonthDay(_year, _month--); if (_month 0) { _month 12; _year--; } } return *this; } Date Date::operator-(int day) { // - 的实现是通过原数值没有更改 所以进行拷贝出来的实例化对象用这个实例化对象进行-操作 Date tmp *this; return tmp - day; }注意点返回值需不需要引用的问题还是考虑是不是临时对象传值后会不会消亡 --的前置后置更改的实现在 和-- 都有前置与后置问题但是运算符有时一模一样就没有办法区分所以C就进行了一个特殊处理有传参的运算符就是后置没有的表示前置一定要int 只要有传参即可区分。operator()//前置 operator(int)//后置 operator--()//前置 operator--(int)//后置代码展示Date Date::operator()//后置 { *this 1; return*this; } Date Date::operator(int)//前置 { Date tmp *this; *this 1; return tmp; } Date Date::operator--()//后置 { *this - 1; return*this; } Date Date::operator--(int)//前置 { Date tmp *this; *this - 1; return tmp; }比较运算符重载 ! bool Date::operator(const Date dat) { return _year dat._year _month dat._month _day dat._day; } bool Date::operator!(const Date dat) { return !(*this dat); } bool Date::operator(const Date dat) { if (_year dat._year) return true; if (_year dat._year _month dat._month) return true; if (_year dat._year _month dat._month _day dat._day) return true; return false; } bool Date::operator(const Date dat) { return !(*this dat); } bool Date::operator(const Date dat) { if (_year dat._year) return true; if (_year dat._year _month dat._month) return true; if (_year dat._year _month dat._month _day dat._day) return true; return false; } bool Date::operator(const Date dat) { return !(*this dat); }其实主要实现的 这三个其他都是利用了!取反的运算符进行实现的。练习题两个日期相减得出两天之间差距多少天。答案在日期类实现中/*天数相减计算天数*/ int operator-(const Date date);2.赋值运算符重载Date tmp *this; Date tmp(*this);上面的代码都是等效的这两个代码都是利用拷贝构造函数实现的但所谓的赋值运算就是比已经实力化对象进行赋值操作就得重新对赋值进行重构操作。int main() { //实例化拷贝构造 Date a(2026, 8, 9); Date b a; b.Print(); //赋值运算 Date c(2026, 8, 9); Date d; d c; d.Print(); return 0; }Date Date::operator(const Date d) { if (*this ! d) { _year d._year; _month d._month; _day d._day; } return *this; }建议在传参加const 防止误操返回值要使用类类型的应用可以支持连续赋值场景在没有赋值重构的时候编译器自动生成一个赋值传参进行一个字节一个字节的拷贝支配性可能容易出现环境不适配的问题Stack 等这种就一定需要赋值重载的情况。3.日期类实现/*天数相减计算天数*/答案不唯一原理实现即可 int Date::operator-(const Date date) { Date tmp *this; int day 0, fu 1; if (*this date) fu -1; while (tmp ! date) { day fu; tmp fu; } return fu*day; }//Data.h #pragma once #include iostream #include stdlib.h #include stdbool.h #include assert.h using namespace std; class Date { public: Date(int year 1, int month 1, int day 1);//构造函数缺省 Date(Date date);//拷贝构造函数 Date(const Date date); void Print();//输出 int GetMonthDay(int year, int month);//取月天数 //运算符重载 /*加减天数改变天数*/ Date operator(int day); Date operator(int day); Date operator-(int day); Date operator-(int day); /* -- 的前置后置更改的实现*/ Date operator();//前置 Date operator(int);//后置 Date operator--();//前置 Date operator--(int);//后置 /*比较天数*/ bool operator(const Date dat)const; bool operator!(const Date dat)const; bool operator(const Date dat)const; bool operator(const Date dat)const; bool operator(const Date dat)const; bool operator(const Date dat)const; /*天数相减计算天数*/ int operator-(const Date date); /*赋值运算符*/ Date operator(const Date d); /*取地址运算符重构*/ Date* operator(); const Date* operator()const; private: int _year; int _month; int _day; };//Data.cpp #define _CRT_SECURE_NO_WARNINGS #include Data.h /************************************* 基本的函数 **********************************************/ //构造 Date::Date(int year, int month, int day) { _year year; _month month; _day day; } //拷贝构造 Date::Date(Date date) { _year date._year; _month date._month; _day date._day; } Date::Date(const Date date) { _year date._year; _month date._month; _day date._day; } /*传年月取月份总天数*/ int Date::GetMonthDay(int year, int month) { static const int month_day[13] { 0,31,28,31,30,31,30,31,31,30,31,30,31 }; if (month 2 ((year % 4 0 year % 100 ! 0) || year % 400 0)) { return 29; } else { return month_day[month]; } } /*输出函数*/ void Date::Print() { cout _year / _month / _day endl; } /********************************** 运算符重载 ***********************************************/ /*加减天数改变天数*/ Date Date::operator(int day) { if (day 0) { return *this - -day; } _day day; while (_day GetMonthDay(_year, _month)) { _day - GetMonthDay(_year, _month); if (_month 13) { _month 1; _year; } } return *this; } Date Date::operator(int day) { Date tmp *this; return tmp day; } Date Date::operator-(int day) { if (day 0) { return *this -day; } _day - day; while (_day 0) { _day GetMonthDay(_year, _month--); if (_month 0) { _month 12; _year--; } } return *this; } Date Date::operator-(int day) { Date tmp *this; return tmp - day; } /* -- 的前置后置更改的实现*/ Date Date::operator()//前置 { *this 1; return*this; } Date Date::operator(int)//后置 { Date tmp *this; *this 1; return tmp; } Date Date::operator--()//前置 { *this - 1; return*this; } Date Date::operator--(int)//后置 { Date tmp *this; *this - 1; return tmp; } /*比较天数*/ bool Date::operator(const Date dat) const { return _year dat._year _month dat._month _day dat._day; } bool Date::operator!(const Date dat) const { return !(*this dat); } bool Date::operator(const Date dat) const { if (_year dat._year) return true; if (_year dat._year _month dat._month) return true; if (_year dat._year _month dat._month _day dat._day) return true; return false; } bool Date::operator(const Date dat) const { return !(*this dat); } bool Date::operator(const Date dat) const { if (_year dat._year) return true; if (_year dat._year _month dat._month) return true; if (_year dat._year _month dat._month _day dat._day) return true; return false; } bool Date::operator(const Date dat) const { return !(*this dat); } /*天数相减计算天数*/ int Date::operator-(const Date date) { Date tmp *this; int day 0, fu 1; if (*this date) fu -1; while (tmp ! date) { day fu; tmp (fu); } return fu*day; } /*赋值运算符*/ Date Date::operator(const Date d) { if (*this ! d) { _year d._year; _month d._month; _day d._day; } return *this; } /*取地址运算符重构*/ Date* Date::operator() { return this; } const Date* Date::operator()const { return this; } int main() { return 0; }取地址运算符重载1.const 成员传参参数可以加const 进行防止误操的情况但我们*this这个时在类里面的我们在调用的时候也可以进行更改但在用有一些函数的时候我们不需要进行修改*this的情况但想要加const就变成个问题所以在C中就提供了一个解决方案在函数括号后加const 进行限定*this。bool Date::operator(const Date dat) const2.取地址运算符重载跟地址有关的有 [] 这两个所也可以通过重构进行。Date* Date::operator() { return this; } const Date* Date::operator()const { return this; }//test.h class Arr { public: Arr(int n4);//构造 int operator[](int n); ~Arr(); private: int* _arr; }; //test.cpp Arr::Arr(int n) { _arr (int*)malloc(sizeof(int) * n); if (_arr NULL) { perror(malloc); exit(1); } } int Arr::operator[](int n) { return _arr[n]; } Arr::~Arr() { free(_arr); _arr NULL; }感谢观看
网站建设高端定制企业官网