网站 建设在作用是什么意思,微信授权登录第三方网站开发,中国做健身补剂的网站,建设部网站业绩如何录入个人主页点击直达#xff1a;小白不是程序媛
C系列专栏#xff1a;C头疼记 目录
前言#xff1a;
运算符重载
运算符重载
赋值运算符重载
前置和后置重载
const成员
取地址及const取地址操作符重载
使用函数操作符重载完成日期类的实现 前言#xff1a;
上篇文…
个人主页点击直达小白不是程序媛
C系列专栏C头疼记 目录
前言
运算符重载
运算符重载
赋值运算符重载
前置和后置重载
const成员
取地址及const取地址操作符重载
使用函数操作符重载完成日期类的实现 前言
上篇文章介绍了在C的类六个成员函数中的三个分别是构造函数、析构函数、拷贝构造函数不知道大家有没有所收获今天我们带来的是剩下的三个函数以及结合这六个函数完成一个完整的日期类的实现让我们开始今天的征程吧 运算符重载
在C中有很多的运算符包括 、- 、* 、/、等等一个两两结合的操作符、--、、等等。
int main()
{int i 0;cout i endl;cout --i endl;i 2;cout i endl;return 0;
} 对于内置类型来说我们可以直接使用但是对于我们自己定义的自定义类型呢该如何使用呢 运算符重载
C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其 返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。函数名字为关键字operator后面接需要重载的运算符符号。函数原型返回值类型 operator操作符(参数列表)
注意 不能通过连接其他符号来创建新的操作符比如operator重载操作符必须有一个类类型参数用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。 示例运算符重载
class Date
{
public:Date(int year 1, int month 1,int day1){_year year;_month month;_day day;}bool operator(const Date y){return _year y._year _month y._month _day y._day;}
private :int _year;int _month;int _day;
}; 赋值运算符重载
赋值运算符重载格式 参数类型const T传递引用可以提高传参效率返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值检测是否自己给自己赋值返回*this 要复合连续赋值的含义 class Date
{
public:Date(int year 1, int month 1,int day1){_year year;_month month;_day day;}Date operator(const Date d){this-_year d._year;this-_month d._month;this-_day d._day;return *this;}
private :int _year;int _month;int _day;
};
赋值运算符只能重载成类的成员函数不能重载成全局函数
class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}int _year;int _month;int _day;
};
// 赋值运算符重载成全局函数注意重载成全局函数时没有this指针了需要给两个参数
Date operator(Date left, const Date right)
{if (left ! right){left._year right._year;left._month right._month;left._day right._day;}return left;
} 原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值 运算符重载只能是类的成员函数。 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。 注意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。 class Date
{
public:void Print(){cout _year - _month - _day endl;}Date(int year 1, int month 1,int day1){_year year;_month month;_day day;}
private :int _year;int _month;int _day;
};
int main()
{Date d1;d1.Print();Date d2 d1;d2.Print();return 0;
} 这里我们没有写赋值重载函数编译器会自动生成一个完成操作和拷贝构造函数优点类似。
注意如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必 须要实现。 前置和后置重载
class Date
{
public:void Print(){cout _year - _month - _day endl;}Date(int year 1, int month 1,int day1){_year year;_month month;_day day;}// 前置返回1之后的结果// 注意this指向的对象函数结束后不会销毁故以引用方式返回提高效率Date operator(){*this 1;return *this;}// 后置// 前置和后置都是一元运算符为了让前置与后置形成能正确重载// C规定后置重载时多增加一个int类型的参数但调用函数时该参数不用传递编译器自动传递// 注意后置是先使用后1因此需要返回1之前的旧值故需在实现时需要先将this保存一份然后给this 1// 而temp是临时对象因此只能以值的方式返回不能返回引用Date operator(int){Date tmp(*this);*this 1;return tmp;}
private :int _year;int _month;int _day;
};
int main()
{Date d1;d1;// 1-1-2d1;// 1-1-1return 0;
} const成员
将const修饰的“成员函数”称之为const成员函数const修饰类成员函数实际修饰该成员函数 隐含的this指针表明在该成员函数中不能对类的任何成员进行修改。
我们来看看下面这段代码
class Date
{
public://void Print( Date *this)void Print(){cout _year - _month - _day endl;}
private:int _year 1;int _month 1;int _day 1;
};
int main()
{const Date d1;//d1.Print(d1)//权限放大d1.Print();return 0;
}
这段代码在编译器上是编译不通过的说明语法有问题。
因为我们创建了一个const Date *的d1将d1作为参数传给函数时函数的的参数是一个Date *两个参数不匹配权限会放大所以编译不通过。
其实函数的形参就是this指针那我们如何将this指针修饰为const呢
只需要在函数声明后面加上const 即可将this指针修饰为const。
class Date
{
public://void Print( Date *this)void Print(){cout _year - _month - _day endl;}
private:int _year 1;int _month 1;int _day 1;
};
int main()
{const Date d1;//d1.Print(d1)//权限放大d1.Print();Date d2;d2.Print();return 0;
}上面为修饰后的代码我们在创建一个普通的Date *能否在const修饰的this指针函数中跑起来呢 答案是可以的因为权限可以平移、缩小不能放大。
那么请思考以下问题 const对象可以调用非const成员函数吗 不可以权限放大。 非const对象可以调用const成员函数吗 可以权限缩小。 const成员函数内可以调用其它的非const成员函数吗 不可以权限放大。 非const成员函数内可以调用其它的const成员函数吗 可以权限缩小。 取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 编译器默认会生成。
class Date
{
public:Date* operator(){return this;}const Date* operator()const{return this;}
private:int _year; // 年int _month; // 月int _day; // 日
};
这两个运算符一般不需要重载使用编译器生成的默认取地址的重载即可只有特殊情况才需 要重载比如想让别人获取到指定的内容
这个函数基本没有什么作用很少用到作为了解即可 使用函数操作符重载完成日期类的实现
void Date::Print()
{cout _year - _month - _day endl;
}
//获取天数
int Date::GetMonthDay(int year, int month)
{int monthArr[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;}return monthArr[month];
}
//构造函数
Date::Date(int year1, int month1, int day1)
{_year year;_month month;_day day;
}
//拷贝构造函数
Date::Date(const Date d)
{this-_year d._year;this-_month d._month;this-_day d._day;
}
//赋值运算符重载
Date Date::operator(const Date d)
{this-_year d._year;this-_month d._month;this-_day d._day;return *this;
}
//日期天数
Date Date::operator(int day)
{_day day;while (_day GetMonthDay(_year, _month)){_day - GetMonthDay(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;
}
//日期天数
Date Date::operator(int day)
{Date tmp(*this);tmp day;return *this;
}
//日期-天数
Date Date::operator-(int day)
{_day - day;while (_day 0){//月小于0时应该先借位--_month;if (_month 0){_year--;_month 12;}_day GetMonthDay(_year, _month);}return *this;
}
//日期-天数
Date Date::operator-(int day)
{Date tmp(*this);tmp - day;return *this;
}
//前置
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 y)
{if (_year y._year){return true;}else if (_year y._year _month y._month){return true;}else if (_year y._year _month y._month _day y._day){return true;}return false;
}
//运算符重载
bool Date::operator(const Date y)
{return _year y._year _month y._month _day y._day;
}
//运算符重载
bool Date::operator(const Date y)
{return *this y || *this y;
}
//运算符重载
bool Date::operator(const Date y)
{return !(*this y);
}
//!运算符重载
bool Date::operator!(const Date y)
{return !(*this y);
}
//日期-日期 返回天数
int Date::operator-(const Date y)
{Date max *this;Date min y;if (*this y){max y;min *this;}int n 0;while (min ! max){min;n;}return n;
} 这里我们使用操作符重载完成了一个简单的日期计算器当然这其中还有很多没有完善的地方。像我们构造一些非法的数据作为日期等等一些小问题我就留给大家了。
C类和对象中的六个成员函数就讲完了大家可以结合上篇文章细细阅读慢慢探索C这六个成员函数的奥秘 总结收获出一些自己的东西。也希望大家留言指出我文章中出现的内容同时也感谢各位看官的三连支持你们的支持就是我更新的动力 下篇预告类和对象下