【C】类与对象篇三1 运算符重载2 赋值运算符重载3 前置和后置重载4 . const成员5 . 取地址及const取地址操作符重载6 . 最后补充1 运算符重载C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数函数名字为关键字operator后面接需要重载的运算符符号。函数原型返回值类型 operator操作符(参数列表)注意1 . 不能通过连接其他符号来创建新的操作符比如operator2 . 重载操作符必须有一个类类型参数3 . 用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义4 . 作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this5 .*(点星号) :: (作用域限定符) sizeof(以字节计算大小) ?: (三目) . (解引用点) 注意以上5个运算符不能重载。这个经常在笔试选择题中出classDate{public:Date(intyear1900,intmonth1,intday1)//全缺省构造函数默认构造函数{_yearyear;_monthmonth;_dayday;}// bool operator(Date* this, const Date d2)// 这里需要注意的是左操作数是this指向调用函数的对象booloperator(constDated2){return_yeard2._year;_monthd2._month_dayd2._day;}private:int_year;int_month;int_day;};2 赋值运算符重载1. 赋值运算符重载格式(1) . 参数类型const T传递引用可以提高传参效率(2) .返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值(3) . 检测是否自己给自己赋值(4) . 返回*this要复合连续赋值的含义classDate{public:Date(intyear1900,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}Date(constDated){_yeard._year;_monthd._month;_dayd._day;}Dateoperator(constDated)//赋值运算符重载格式,传递引用可以提高传参效率{if(this!d)//检测是否自己给自己赋值{_yeard._year;_monthd._month;_dayd._day;}return*this;}private:int_year;int_month;int_day;};2. 赋值运算符只能重载成类的成员函数不能重载成全局函数原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值运算符重载只能是类的成员函数。3. 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。即浅拷贝注意:内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值classTime{public:Time(){_hour1;_minute1;_second1;}Timeoperator(constTimet){if(this!t)//检测是否自己给自己赋值{_hourt._hour;_minutet._minute;_secondt._second;}return*this;}private:int_hour;int_minute;int_second;};classDate{private:// 基本类型(内置类型)int_year1970;int_month1;int_day1;// 自定义类型Time _t;};intmain(){Date d1;Date d2;Date d3;d1d2;d1d2d3;//支持连续赋值return0;}4 . 注意如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必须要实现即需要深拷贝。3 前置和后置重载classDate{public:Date(intyear1900,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}// 前置返回1之后的结果// 注意this指向的对象函数结束后不会销毁故以引用方式返回提高效率Dateoperator(){_day1;return*this;}// 后置// 前置和后置都是一元运算符为了让前置与后置形成能正确重载// C规定后置重载时多增加一个int类型的参数但调用函数时该参数不用传递编译器自动传递// 注意后置是先使用后1因此需要返回1之前的旧值故需在实现时需要先将this保存一份然后给this1// 而temp是临时对象因此只能以值的方式返回不能返回引用Dateoperator(int){Datetemp(*this);_day1;returntemp;}private:int_year;int_month;int_day;};intmain(){Date d;Dated1(2022,1,13);dd1;// d: 2022,1,13 d1:2022,1,14dd1;// d: 2022,1,15 d1:2022,1,15return0;}4 . const成员将const修饰的“成员函数”称之为const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改classDate{public:Date(intyear,intmonth,intday){_yearyear;_monthmonth;_dayday;}voidPrint(){coutPrint()endl;coutyear:_yearendl;coutmonth:_monthendl;coutday:_dayendlendl;}voidPrint()const{//_year 2025;会报错表达式应该为可修改的左值coutPrint()constendl;coutyear:_yearendl;coutmonth:_monthendl;coutday:_dayendlendl;}private:int_year;// 年int_month;// 月int_day;// 日};intmain(){Dated1(2022,1,13);d1.Print();constDated2(2022,1,13);d2.Print();return0;}运行结果什么时候类中的成员函数应该加const类比 为什么不可变序也是权限问题const对象可以调用非const成员函数吗答由上图可知不可以权限不可放大非const对象可以调用const成员函数吗答由上图可知可以权限可以缩小const成员函数内可以调用其它的非const成员函数吗答不可以如下图非const成员函数内可以调用其它的const成员函数吗答可以5 . 取地址及const取地址操作符重载这两个默认成员函数一般不用重新定义 编译器默认会生成。classDate{public:Date*operator(){returnthis;}constDate*operator()const{returnthis;}private:int_year;// 年int_month;// 月int_day;// 日};这两个运算符一般不需要重载使用编译器生成的默认取地址的重载即可只有特殊情况才需要重载比如想让别人获取到指定的内容6 . 最后补充(1) . cout 对于运算符 库里面通过函数重载的方式来达到自动识别内置类型的目的(2) . cout 本质:(3) . 权限问题