当前位置: 首页 > news >正文

asp网站开发pdf软件设计师通过率

asp网站开发pdf,软件设计师通过率,wordpress网站备案号,怀化物流网站建设报价目录 构造函数补充 构造函数初始化列表的使用 赋值运算符重载函数 运算符重载函数介绍 运算符重载函数的使用 赋值运算符重载函数 赋值运算符重载函数的使用 拷贝构造函数和赋值运算符重载函数 重载前置和后置 前置 后置 重载流插入与流提取 流插…目录 构造函数补充 构造函数初始化列表的使用 赋值运算符重载函数 运算符重载函数介绍 运算符重载函数的使用 赋值运算符重载函数 赋值运算符重载函数的使用 拷贝构造函数和赋值运算符重载函数 重载前置和后置 前置 后置 重载流插入与流提取 流插入运算符重载 流提取运算符重载 const成员函数 取地址操作符重载与const成员取地址操作符重载 实现日期类练习 声明本篇为C默认构造函数最后一篇 构造函数补充 在C中可以在构造函数的函数体中为变量进行初始化但是实际上该过程并不是初始化可以理解为赋值因为对象还没有真正创建并且初始化只能初始化一次但是赋值可以执行多次而当对象创建时所有成员变量就是当成整体创建那么每一个变量在和何处被初始化变成了一个问题为了解决这个问题C标准中引入构造函数初始化列表只要是本类的成员变量都是在初始化列表处初始化具体初始化的内容由程序员自己决定 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 23):_year(year), _month(month), _day(day){}void print(){cout _year / _month / _day endl;} };int main() {Date d;d.print();return 0; } 输出结果 2024/3/23 构造函数初始化列表的使用 初始化列表以一个冒号开始接着是一个以逗号分隔的数据成员列表每个成员变量后面跟一个放在括号中的初始值或表达式语法如下 类名(参数列表) :成员变量(值) ,成员变量(值) ,成员变量(值) {} 注意并不是所有成员变量都需要写进初始化列表没写入初始化列表的成员变量也会像写入初始化列表中的成员变量一样走一遍初始化列表只是没有显式 1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次) 2. 类中包含以下成员必须放在初始化列表位置进行初始化 引用成员变量 #include iostream #include cstdlib #include cassert using namespace std;class Array { private:int* _arr;int _size;int ref; public:Array():_arr(nullptr), _size(4), ref(_size)//引用类型必须初始化{_arr (int*)malloc(sizeof(int) * _size);assert(_arr);}Array(const Array data):ref(_size)//拷贝构造中引用类型也必须初始化{_arr (int*)malloc(sizeof(int) * data._size);assert(_arr);for (int i 0; i data._size; i){_arr[i] data[i];}}//重载[]int operator[](int i){return _arr[i];}//const类型的引用不可以通过返回的引用改变数组中的值const int operator[](int i) const{return _arr[i];} };int main() {Array a;for (int i 0; i 4; i){a[i] i 1;}const Array p(a);for (int i 0; i 4; i){cout p[i] ;}return 0; } 输出结果 1 2 3 4 const成员变量自定义类型成员(且该类没有默认构造函数时) #include iostream using namespace std;class Time { private:int _time; public:Time(int time){} };class Date { private:int _year;int _month;int _day;Time _t; public:Date():_year(2023),_month(3),_day(21){} };int main() {Date d;return 0; } 报错信息 类 Time 不存在默认构造函数 在C11标准规范中可以在成员变量创建的同时给缺省值此时如果给了这个缺省值想使用缺省值时就不需要再将该成员变量写入初始化列表中如果不想使用缺省值则将成员变量写入初始化列表中并给定初始值否则默认初始值为0 #include iostream using namespace std;//构造函数初始化列表 class Date { private:int _year 2023;int _month 2;int _day 28; public:Date()//_year没有写入初始化列表使用缺省值: _month(3)//写入初始化列表中给了初始值为3使用初始值, _day()//写入初始化列表中但是没给初始值默认初始值为0{}void print(){cout _year / _month / _day endl;} };int main() {Date d;d.print();return 0; } 输出结果 2023/3/0 在初始化列表中无法处理例如动态申请内存的行为此时可以在函数体内完成例如 #include iostream #include cstdlib #include cassert using namespace std;class Array { private:int* _arr;int _size; public:Array():_arr(nullptr),_size(4){_arr (int*)malloc(sizeof(int) * _size);//在构造函数体中分配空间assert(_arr);}Array(const Array data){_arr (int*)malloc(sizeof(int) * data._size);assert(_arr);for (int i 0; i data._size; i){_arr[i] data[i];}}//重载[]int operator[](int i){return _arr[i];}const int operator[](int i) const{return _arr[i];} };int main() {Array a;for (int i 0; i 4; i){a[i] i 1;}const Array p(a);for (int i 0; i 4; i){cout p[i] ;}return 0; } 输出结果 1 2 3 4 所以如果不使用缺省值尽量使用初始化列表初始化因为不管是否使用初始化列表对于自定义类型的成员变量一定会先使用初始化列表初始化 注意成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关 class A { public:A(int a):_a1(a),_a2(_a1){}void Print() {cout_a1 _a2endl;} private:int _a2;int _a1; }; int main() {A aa(1);aa.Print(); } 输出结果 1 -858993460 在上面的代码中因为成员变量_a2比_a1先声明所以在初始化时先走_a2(_a1)所以_a2被初始化为随机值接着再初始化_a1所以_a1为1 赋值运算符重载函数 运算符重载函数介绍 在C中为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;} };int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//自定义类型无法使用内置的关系运算符进行比较return 0; } 报错信息 二进制“”:“Date”不定义该运算符或到预定义运算符可接收的类型的转换 为了自定义类型的对象之间可以进行关系运算可以使用运算符重载如下面代码 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int getYear(){return _year;}int getMonth(){return _month;}int getDay(){return _day;} };bool operator(Date d1, Date d2) {return d1.getYear() d2.getYear() d1.getMonth() d2.getMonth() d1.getDay() d1.getDay(); }int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//有重载的函数时可以比较return 0; } 输出结果 1 运算符重载函数的使用 对于运算符重载函数来说其函数名为operator需要重载的运算符而该函数的原型如下 函数返回类型 operator运算符(参数列表) 定义运算符重载函数时需要注意下面的问题 不能通过连接其他符号来创建新的操作符比如operator 重载操作符必须有一个类类型参数用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.* :: sizeof ?: . 注意以上5个运算符不能重载 对于下面的代码 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int getYear(){return _year;}int getMonth(){return _month;}int getDay(){return _day;} };//全局运算符重载函数 bool operator(Date d1, Date d2) {return d1.getYear() d2.getYear() d1.getMonth() d2.getMonth() d1.getDay() d1.getDay(); }int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//有重载的函数时可以比较return 0; } 输出结果 1 在上面的代码中因为运算符重载函数不在类中并且因为类的成员变量为private所以需要调用获取函数来得到当前对象的成员变量中的值并且因为在全局中并不存在哪一个对象调用函数所以没有this指针此时形参的个数对应运算符的操作数的个数 注意上面的全局运算符重载函数中形参不可以使用const修饰因为如果使用了const修饰那么就是d1和d2都是const修饰的对象而this只是*const而不是const*本来是d1和d2被const修饰不可以修改引用的对象的值但是如果传递给了this可能会出现通过this改变d1和d2引用的对象的值所以此处涉及到将引用的权限放大 考虑到如果将运算符重载函数写在类外需要额外写三个函数来获取到指定的值所以可以将运算符重载函数写进类中 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}//类中的运算符重载函数bool operator(const Date d){return _year d._year _month d._month _day d._day;} };int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//直接调用类中实现的运算符重载函数//上面的代码相当于cout d1.operator(d2) endl;return 0; } 输出结果: 1 在上面的代码中因为运算符重载函数在类中所以存在this指针所以只需要传递一个参数加上this指针参数和额外的参数一共两个参数对应操作符的操作数个数并且形参对象引用d指的是第二个操作数因为d1 d2等价于d1.operator(d2)因为是d1在调用运算符重载函数所以this指针指向的对象即为d1 赋值运算符重载函数 赋值运算符重载函数也是运算符重载函数中的一种因为重载的运算符为赋值运算符重载赋值运算符时首先不能改变赋值运算符的特性包括连续赋值 赋值运算符重载函数的使用 赋值运算符重载函数的格式 参数类型const T传递引用可以提高传参效率T为类名返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值并且需要检测是否自己给自己赋值以减少赋值次数返回*this 要复合连续赋值的含义 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}void operator(const Date d){_year d._year;_month d._month;_day d._day;} };int main() {Date d(2024, 2, 28);Date d1;d1 d;d1.print();return 0; } 输出结果 2024/2/28 在上面的代码中类Date中对赋值运算符进行了重载将引用指向的对象中的值给调用该运算符重载函数的对象但是上面的代码无法实现赋值运算符的连续赋值因为没有返回值 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}void operator(const Date d){_year d._year;_month d._month;_day d._day;} };int main() {Date d(2024, 2, 28);Date d1;Date d2;d1 d;d1.print();d2 d1 d;return 0; } 报错信息 二元“”: 没有找到接受“void”类型的右操作数的运算符(或没有可接受的转换) 所以为了解决这个问题赋值运算符重载函数需要给定返回值为类类型 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}Date operator(const Date d){_year d._year;_month d._month;_day d._day;return *this;} };int main() {Date d(2024, 2, 28);Date d1;Date d2;d2 d1 d;d1.print();d2.print();return 0; } 输出结果 2024/2/28 2024/2/28 在上面的代码中赋值运算符重载函数给了返回值为Date类型的引用此时可以使用连续赋值因为赋值运算符从右往左结合所以具体过程为d对象赋值给d1d1对象的值赋值给d2从函数调用的角度理解为d2.operator(d1.operator(d));注意不是d2.operator(d1).operator(d);本句理解为d2被赋值为d1中的内容然后再被赋值为d中的内容相当于d2 d1; d2 d; 赋值运算符重载函数的返回值也可以不用引用但是此时在返回时会调用拷贝构造函数将返回值的内容拷贝给调用赋值运算符重载函数的对象为了减少调用拷贝构造的次数更推荐使用引用该解释同样适用于形参 另外还有一个小问题如果两个相同的对象进行赋值那么将产生额外的一次赋值对于这个问题在赋值时需要判断形参引用的对象和this指针指向的对象是否是同一个地址的对象 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} };int main() {Date d(2024, 2, 28);d d;return 0; } 在上面的代码中判断this指针指向的对象的地址和引用的对象地址是否相等如果二者相等则证明是同一个对象不需要进行赋值直接返回即可注意形参的Date d为创建对象的引用而if语句中的d是取引用的地址 注意赋值运算符重载函数必须作为成员函数不能作为全局函数 #include iostream using namespace std;class Date { public:int _year;int _month;int _day;Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;} }; Date operator(Date d1, Date d) { if (d1 ! d){d1._year d._year;d1._month d._month;d1._day d._day;}return d1; } int main() {Date d(2024, 2, 28);Date d1;d1 d;return 0; } 报错信息 “operator”必须是成员函数 赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了所以赋值运算符重载只能是类的成员函数 拷贝构造函数和赋值运算符重载函数 与拷贝构造函数类似赋值运算符重载函数如果用户没有实现编译器会自动实现。默认如果不自主实现还是按照字节拷贝按照字节方式拷贝也会遇到像拷贝函数一样的问题指对象中有资源申请时 一个对象改变另一个对象也会跟着改变严重者会数据覆盖释放资源时会因为多次释放一个空间导致程序崩溃 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}};int main() {Date d(2024, 2, 28);Date d1;d1 d;//编译器自动生成的默认赋值运算符重载函数Date d2(d);//编译器自动生成的拷贝构造函数d1.print();d2.print();return 0; } 输出结果 2024/2/28 2024/2/28 与拷贝构造函数一样如果类对象中有涉及到资源申请那么需要自己实现赋值运算符重载函数否则直接使用默认的即可 重载前置和后置 前置 对于运算符重载函数的使用规则那么可以很容易写出的重载函数如下 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}void operator(){_day 1;} };int main() {Date d;d;d.print();return 0; } 输出结果 2024/3/23 因为前相当于计算1而因为前面实现过获取X天后的日期的函数GetAfterXDays_plusEqual所以可以直接用该函数进行复用从而实现操作 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int GetMonthDays(int year, int month){int monthDays[] { 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 monthDays[month] 1;} else{return monthDays[month];}}Date GetAfterXDays_plusEqual(int days){_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;}Date GetAfterXDays_plus(int days){Date tmp(*this);tmp._day days;while (tmp._day GetMonthDays(tmp._year, tmp._month)){tmp._day - GetMonthDays(tmp._year, tmp._month);tmp._month;if (tmp._month 13){tmp._year;tmp._month 1;}}return tmp;}void operator(){//因为相当于1所以可以直接复用GetAfterXDays_plusEqual(1)*this GetAfterXDays_plusEqual(1);} };int main() {Date d;d;d.print();return 0; } 输出结果 2024/3/23 注意到上面实现的是无返回值的运算符重载函数但是如果函数没有返回值将无法将后的值给另外一个对象 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int GetMonthDays(int year, int month){int monthDays[] { 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 monthDays[month] 1;} else{return monthDays[month];}}Date GetAfterXDays_plusEqual(int days){_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;}Date GetAfterXDays_plus(int days){Date tmp(*this);tmp._day days;while (tmp._day GetMonthDays(tmp._year, tmp._month)){tmp._day - GetMonthDays(tmp._year, tmp._month);tmp._month;if (tmp._month 13){tmp._year;tmp._month 1;}}return tmp;}void operator(){//_day 1;//因为相当于1所以可以直接复用GetAfterXDays_plusEqual(1)*this GetAfterXDays_plusEqual(1);//return *this;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} };int main() {Date d;d;d.print();Date d1;d1 d;return 0; } 报错信息 二元“”: 没有找到接受“void”类型的右操作数的运算符(或没有可接受的转换) 所以为了解决这种问题将考虑为运算符重载函数加上返回值为类对象引用类型 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int GetMonthDays(int year, int month){int monthDays[] { 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 monthDays[month] 1;} else{return monthDays[month];}}Date GetAfterXDays_plusEqual(int days){_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;}Date GetAfterXDays_plus(int days){Date tmp(*this);tmp._day days;while (tmp._day GetMonthDays(tmp._year, tmp._month)){tmp._day - GetMonthDays(tmp._year, tmp._month);tmp._month;if (tmp._month 13){tmp._year;tmp._month 1;}}return tmp;}Date operator(){//_day 1;//因为相当于1所以可以直接复用GetAfterXDays_plusEqual(1)*this GetAfterXDays_plusEqual(1);return *this;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} };int main() {Date d;d;d.print();Date d1;d1 d;return 0; } 输出结果 2024/3/23 后置 上面的函数中实现了前置但是并没有实现后置如果在没有实现后置时使用后置则会出现下面的情况 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int GetMonthDays(int year, int month){int monthDays[] { 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 monthDays[month] 1;}else{return monthDays[month];}}Date GetAfterXDays_plusEqual(int days){_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;}Date GetAfterXDays_plus(int days){Date tmp(*this);tmp._day days;while (tmp._day GetMonthDays(tmp._year, tmp._month)){tmp._day - GetMonthDays(tmp._year, tmp._month);tmp._month;if (tmp._month 13){tmp._year;tmp._month 1;}}return tmp;}Date operator(){//_day 1;//因为相当于1所以可以直接复用GetAfterXDays_plusEqual(1)*this GetAfterXDays_plusEqual(1);return *this;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} };int main() {Date d;d;return 0; } 报错信息 二进制“”:“Date”不定义该运算符或到预定义运算符可接收的类型的转换 所以有前置的实现并不能同时应用于后置对于后置来说编译器为了与前置作区分需要在形参位置添加一个整型占位形参如下 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int GetMonthDays(int year, int month){int monthDays[] { 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 monthDays[month] 1;}else{return monthDays[month];}}Date GetAfterXDays_plusEqual(int days){_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this;}Date GetAfterXDays_plus(int days){Date tmp(*this);tmp._day days;while (tmp._day GetMonthDays(tmp._year, tmp._month)){tmp._day - GetMonthDays(tmp._year, tmp._month);tmp._month;if (tmp._month 13){tmp._year;tmp._month 1;}}return tmp;}//前置Date operator(){//_day 1;//因为相当于1所以可以直接复用GetAfterXDays_plusEqual(1)*this GetAfterXDays_plusEqual(1);return *this;}//后置但是为了不同于前置在形参处加入int形参作为占位便于编译器区分Date operator(int){//后置满足先使用再所以返回值为原值Date tmp(*this);*this GetAfterXDays_plusEqual(1);return tmp;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;} };int main() {Date d;d;d.print();return 0; } 输出结果 2024/3/23 在上面的代码中对于后置重载函数来说在形参处添加了一个int类型形参作为占位符这个形参可以不给形参名因为只是编译器用于区分 重载流插入与流提取 在C标准库中cout和cin是属于iostream中ostream和istream的对象对于流插入运算符之所以cout输出可以不用指定占位符编译器可以自动匹配的原因是ostream中的运算符重载和函数重载对于内置类型来说有下面的函数重载 同样对于流提取运算符来说也是如此如下图所示 但是流插入和流提取运算符并没有对自定义类型有函数重载所以可以对流提取运算符和流插入运算符进行函数重载 流插入运算符重载 按照前面的运算符重载思路可以写出下面的代码 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void operator(ostream cout){cout _year / _month / _day endl;} };int main() {Date d;cout d;return 0; } 报错信息 二元“”: 没有找到接受“Date”类型的右操作数的运算符(或没有可接受的转换) 在上面的代码中虽然重载了但是形参是ostream流的对象而隐含的形参是this而在运算符重载函数形参列表的规则中对于有两个操作数的运算符重载来说第一个参数为左操作数第二个参数为右操作数所以上面的代码调用应该为d cout #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}void operator(ostream cout){cout _year / _month / _day endl;} };int main() {Date d;//cout d;d cout;return 0; } 输出结果 2024/3/22 但是和正常的输出刚好顺序相反所以这种方法需要改变但是因为不能改变this在形参的位置所以考虑到将重载放置到全局中此时可以决定两个操作数的顺序但是这个方法就不能使用this指针并且需要考虑到成员变量的private属性本处给出一种解决方案是使用get函数 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}int getYear(){return _year;}int getMonth(){return _month;}int getDay(){return _day;} };void operator(ostream cout, Date d) {cout d.getYear() / d.getMonth() / d.getDay() endl; }int main() {Date d;cout d;return 0; } 输出结果 2024/3/22 在上面的代码中将流插入运算符重载函数放置到全局中可以控制cout和d的顺序此时即可写为cout d但是因为上面的并没有返回值所以不可以连续插入所以可以改进为如下 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}int getYear(){return _year;}int getMonth(){return _month;}int getDay(){return _day;} };ostream operator(ostream cout, Date d) {cout d.getYear() / d.getMonth() / d.getDay() endl;return cout; }int main() {Date d;Date d1;cout d d1 endl;return 0; } 输出结果 2024/3/22 2024/3/22 流提取运算符重载 对于流提取运算符的重载类似于流插入运算符但是此时不能使用获取函数所以对于流提取运算符的重载来说考虑用友元解决使用友元可以让全局函数中的对象获取到private属性的变量 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}//友元friend istream operator(istream cin, Date d);int getYear(){return _year;}int getMonth(){return _month;}int getDay(){return _day;} };ostream operator(ostream cout, Date d) {cout d.getYear() / d.getMonth() / d.getDay() endl;return cout; }istream operator(istream cin, Date d) {cin d._year d._month d._day;return cin; }int main() {Date d;Date d1;cin d d1;cout d d1 endl;return 0; } 输入 2024 2 28 2024 3 31 输出结果 2024/2/28 2024/3/31 使用友元解决流插入运算符的重载函数 #include iostream using namespace std;class Date { private:int _day;int _month;int _year; public:Date(int year 2024, int month 3, int day 22){_year year;_month month;_day day;}//友元friend istream operator(istream cin, Date d);friend ostream operator(ostream cout, Date d); };ostream operator(ostream cout, Date d) {cout d._year / d._month / d._day endl;return cout; }istream operator(istream cin, Date d) {cin d._year d._month d._day;return cin; }int main() {Date d;Date d1;cin d d1;cout d d1 endl;return 0; } 输入 2024 2 23 2022 3 31 输出结果 2024/2/23 2022/3/31 const成员函数 将const修饰的“成员函数”称之为const成员函数const修饰类成员函数实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改 在前面的运算符重载函数中当运算符重载函数在全局时不可以使用const修饰形式参数因为const成员变量传递给成员函数时涉及到引用权限放大那么const成员函数就是用来解决这种权限放大问题可以将权限保持不变或者缩小例如在下面的代码中 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int getYear() const{return _year;}int getMonth() const{return _month;}int getDay() const{return _day;} };//全局运算符重载函数const形参 bool operator(const Date d1, const Date d2) {return d1.getYear() d2.getYear() d1.getMonth() d2.getMonth() d1.getDay() d1.getDay(); }int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//有重载的函数时可以比较return 0; } 输出结果 1 在上面的代码中使用const修饰了运算符重载函数的两个形式参数此时d1和d2不可以被修改当对象d1和d2调用get系列函数时成员函数的形式参数需要保证获得的权限不被放大所以需要修饰形式参数但是因为this指针不可以直接显式做形式参数所以不可以使用const显式对this指针进行修饰此时就需要将const放置到函数名后作为修饰this指针的const以满足指针及引用权限不被放大 但是如果运算符重载函数中的两个形式参数并不是const修饰的变量此时调用const成员函数也不会有错因为此时是权限的缩小从可修改到成员函数的不可修改如下面的代码 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}void print(){cout _year / _month / _day endl;}int getYear() const{return _year;}int getMonth() const{return _month;}int getDay() const{return _day;} };//全局运算符重载函数非const形参 bool operator(Date d1, Date d2) {return d1.getYear() d2.getYear() d1.getMonth() d2.getMonth() d1.getDay() d1.getDay(); }int main() {Date d1;Date d2(d1);cout (d1 d2) endl;//有重载的函数时可以比较return 0; } 对于const成员函数和非const成员函数之间也是如此 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}//非const成员函数void printYear(){cout _year;} int getYear() const{printYear();return _year;} };int main() {Date d1;Date d2(d1);return 0; } 报错信息 “void Date::printYear(void)”: 不能将“this”指针从“const Date”转换为“Date ” 而对于const成员函数和const成员函数之间可以直接调用 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}//非const成员函数void printYear() const{cout _year;} int getYear() const{printYear();return _year;} };int main() {Date d1;Date d2(d1);return 0; } 同样非const成员函数可以调用const成员函数 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}//非const成员函数void printYear() const{cout _year;} int getYear() {printYear();return _year;} };int main() {Date d1;Date d2(d1);return 0; } 取地址操作符重载与const成员取地址操作符重载 在C中这两个运算符重载函数可以不用显式定义编译器会默认生成 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}};int main() {Date d1;Date d2;const Date d3;cout d1 endl;cout d2 endl;cout d3 endl;return 0; } 输出结果 00000031E9FEF628 00000031E9FEF658 00000031E9FEF688 也可以显式定义 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}Date* operator(){return this;}const Date* operator()const{return this;}};int main() {Date d1;Date d2;const Date d3;cout d1 endl;cout d2 endl;cout d3 endl;return 0; } 输出结果 0000006B086FFC38 0000006B086FFC68 0000006B086FFC98 只有特殊情况才需要重载这两个函数比如想让别人获取到指定的内容让其访问非法地址 #include iostream using namespace std;class Date { private:int _year;int _month;int _day; public:Date(int year 2024, int month 3, int day 21){_year year;_month month;_day day;}Date* operator(){return (Date*)0;}const Date* operator()const{return (Date*)0;}};int main() {Date d1;Date d2;const Date d3;cout d1 endl;cout d2 endl;cout d3 endl;return 0; } 输出结果 0000000000000000 0000000000000000 0000000000000000 实现日期类练习 //头文件 #pragma once#include iostream using namespace std;class Date { private:int _day;int _month;int _year;public://构造函数Date(int year 2024, int month 3, int day 23):_year(year),_month(month),_day(day){}friend inline istream operator(istream cin, Date d);friend inline ostream operator(ostream cout, Date d);//获取月份日期函数int GetMonthDays(int year, int month);//运算符重载Date operator(int days);//运算符重载Date operator(int days){Date tmp(*this);//复用重载tmp days;return tmp;}//赋值运算符重载Date operator(const Date d);//前置运算符重载Date operator(){//复用重载*this 1;return *this;}//后置运算符重载Date operator(int){//复用函数Date tmp(*this);tmp 1;return tmp;}//运算符重载bool operator(const Date d) const;//运算符重载bool operator(const Date d) const;//运算符重载bool operator(const Date d) const{//的对立事件为故直接对取反return !(*this d);}//运算符重载bool operator(const Date d) const{//的对立事件为故直接对取反return !(*this d);}//运算符重载bool operator(const Date d) const{return _year d._year _month d._month _day d._day;}//!运算符重载bool operator!(const Date d) const{//!的对立事件为故直接对取反return !(*this d);}//-运算符重载Date operator-(int days);//-运算符重载Date operator-(int days){Date tmp(*this);tmp._day - days;return tmp;}//前置--运算符重载Date operator--(){//复用-重载函数*this - 1;return *this;}//后置--运算符重载Date operator--(int){//复用-重载Date tmp(*this);*this - 1;return tmp;}//日期-日期int operator-(const Date d); };inline ostream operator(ostream cout, Date d) {cout d._year / d._month / d._day endl;return cout; }inline istream operator(istream cin, Date d) {cin d._year d._month d._day;return cin; }//实现文件 #define _CRT_SECURE_NO_WARNINGS 1 #include Date_class.h//获取月份日期函数 int Date::GetMonthDays(int year, int month) {int monthDays[] { 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 monthDays[month] 1;}return monthDays[month]; }//运算符重载 Date Date::operator(int days) {_day days;while (_day GetMonthDays(_year, _month)){_day - GetMonthDays(_year, _month);_month;if (_month 13){_year;_month 1;}}return *this; }//赋值运算符重载 Date Date::operator(const Date d) {if (this ! d){_year d._year;_month d._month;_day d._day;}return *this; }//运算符重载 bool Date::operator(const Date d) const {//如果年大就直接返回trueif (_yeard._year){return true;}else if(_year d._year _month d._month)//年相等时比较月份月份大就直接返回true{return true;}else if (_year d._year _month d._month _day d._day)//年相等月份相等时天大就直接返回true{return true;}else//其他情况均返回false{return false;} }//运算符重载 bool Date::operator(const Date d) const {//如果年小就直接返回trueif (_year d._year){return true;}else if (_year d._year _month d._month)//年相等时比较月份月份小就直接返回true{return true;}else if (_year d._year _month d._month _day d._day)//年相等月份相等时天小就直接返回true{return true;}else//其他情况均返回false{return false;} }//-运算符重载 Date Date::operator-(int days) {_day - days;while (_day 0){_month--;if (_month 0){_year--;_month 12;}_day GetMonthDays(_year, _month);}return *this; }//日期-日期 int Date::operator-(const Date d) {Date maxYear *this;Date minYear d;int flag 1;if (maxYear minYear){maxYear d;minYear *this;flag -1;}int count 0;while (maxYear ! minYear){count;minYear;}return count * flag; }//测试文件 #define _CRT_SECURE_NO_WARNINGS 1 #include Date_class.hint main() {Date d;Date d1(d);Date d2(2023, 1, 1);d--;cout d;cout (d ! d1) endl;cout (d d1) endl;Date d3;d3 --d2;cout d3;Date d4(2023, 2, 7);d4 - 100;cout d4;cout d4 - d1 endl;Date d5;Date d6;cin d5 d6;cout d5 d6 endl;return 0; } 输入 2024 3 23 2023 2 23 输出结果 2024/3/22 1 0 2022/12/31 2022/10/30 -510 2024/3/23 2023/2/23
http://www.ho-use.cn/article/10816435.html

相关文章:

  • 网站建设建设哪家好合肥竞价推广
  • 百色网站建设温州网站推广哪家好
  • 网站和管理系统哪个更难做建立企业的网站有哪几种方案
  • 宁波seo网站服务wordpress友链模板
  • 漳州北京网站建设品牌家具排行榜前十名
  • 如何自己免费制作网站网站开发常用js函数
  • 网站搭建哪里找方便广州网站开发公司
  • 团队合作网站仓储网站建设
  • 网站建设 英语翻译湖南seo优化服务
  • 网站搬家内页打不开口碑好的专业网站建设
  • 淄博网站建设 招聘高端创意网站建设
  • 可视化建网站素材网站怎么推广
  • 订餐网站怎么做短视频平台
  • 临海城市建设网站免费外链网盘
  • 网站建设合同任wordpress标签工具
  • 网站建设的项目总结什么是企业网站建设
  • 如何上传网站到云主机服装定制网站模板
  • 联合实验室 网站建设方案阿里云域名续费
  • 自己能否建立公司网站dw个人主页制作代码
  • 企业网站的制作哪家好企业案例网站
  • 企梦云网站建设php商城网站开发实例视频教程
  • 建设一个用教育网站网站建立的步骤
  • 乐清网站网络公司个人做分类信息网站
  • 北京做手机网站建设高端品牌网站建设定位
  • 什么是权重高的网站linux类似wordpress
  • 商业网站建设所用软件做正规网站
  • 婚纱网站模板素材花生壳怎么建设购物网站
  • 刘素云网站脱孝怎样做广州网站建设制作的公司
  • dw做的网站如何使用wordpress画廊怎么用
  • 婚庆类网站模板做的比较好的猎头网站