类与对象4

it2023-11-25  73

类的6个默认成员函数 构造函数、析构函数、拷贝构造函数、赋值操作符重载、const成员函数、取地址及const取地址操作符重载

拷贝构造函数: 构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。 特征: 1.拷贝构造函数是构造函数的一个重载形式; 2.拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用; 3.若未显示定义,系统生成默认的拷贝构造函数,默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝是浅拷贝,或者值拷贝。

赋值运算符重载 运算符重载 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数。也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为:关键字operator后面接需要重载的运算符符号。 函数原型:返回值类型operator操作符(参数列表) 注意:不能通过链接其他符号来创建新的操作符:比如operator@;重载操作符必须有一个类类型或者枚举类型的操作数;用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义;作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参;.、::、sizeof、?:、.这5个运算符不能重载。 赋值运算符重载 1.一般地,参数是函数所在类的const类型的引用; 2.返回this; 3.检测是否自己给自己赋值; 4.一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的只拷贝。

const成员 const修饰类的成员函数 将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。 const对象不可以调用非const成员函数,只可调用const成员函数; 非const对象可以调用const成员函数,也可调用非const成员函数; const成员函数内不可以调用其他的非const成员函数; 非const成员函数内可以调用其他的const成员函数。

取地址及const取地址操作符 这两个默认成员函数一般不用重新定义,编译器默认会生成。

日期类的实现

#include<iostream> #include<string.h> #include<stdlib.h> #include<Windows.h> using namespace std; class Date { public: Date(int year = 1900,int month=1,int day=1) { //判断日期是否有效 if(year<=0||month<=0||month>12||day<0||day>Getday(year,month)) { cout<<"无效日期"<<endl; cout<<"日期重置为:1900-1-1"<<endl; _year=1900; _month=1; _day=1; } else { _year=year; _month=month; _day=day; } } int Getday(int year,int month) { static int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //static 1.全局变量:限制全局变量在当前文件可见 //2.函数:限制函数在当前文件可见 //3.局部变量:延长局部变量的生命周期,让局部变量的生命周期的程序的生命周期相同 int day=days[month]; if(month=2) { if((year%4==0 && year%100!=0)||year%400==0) ++day; } return day; } Date& operator+=(int day) { if (day<0) { return *this -= -day; } _day+=day; while(_day>Getday(_year,_month)) { _day-=Getday(_year,_month); _month++; if(_month==13) { _month=1; ++_year; } } return *this; } Date& operator-=(int day) { /*if(day<_day) { //_day-=day; }*/ if (day<0) { return *this +=-day; } _day-=day; while(day>=_day) { --_month; if(_month==0) { --_year; _month=12; } _day+=Getday(_year,_month); } return *this; } Date operator-(int day) { Date tmp(*this); return tmp-=day; } Date& operator--() { return *this-=1; }//前置-- Date operator--(int) { Date tmp(*this); *this-=1; return tmp; }//后置-- //前置++ Date& operator++() { return *this+=1; } //后置++ Date operator++(int) { Date tmp(*this); *this+=1; return tmp; } //运算符重载 bool operator<(const Date& d) { if(_year<d._year) return true; else if(_year==d._year) { if(_month<d._month) return true; else if(_month==d._month) { if(_day<d._day) { return true; } } } return false; } bool operator>(const Date& d) { if(_year>d._year) return true; else if(_year==d._year) { if(_month>d._month) return true; else if(_month==d._month) { if(_day>d._day) { return true; } } } return false; //return !(*this<=d); } bool operator==(const Date& d) { return _year==d._year&&_month==d._month&&_day==d._day; } bool operator!=(const Date& d) { //return !(_year==d._year&&_month==d._month&&_day==d._day); return !(*this==d); } bool operator<=(const Date& d) { //return (operator<(d) || operator==(d)); //return (*this).operator<(d) || (*this).operator==(d); //return this->operator<(d)||this->operator==(d); return (*this<d)||(*this==d); } bool operator>=(const Date& d) { //return (operator>(d) || operator==(d)); return !(*this<d); } //日期减日期 int operator-(const Date& d) { //相加 判等 大小比较 Date max=*this; Date min=d; int flag=1; if(min>max) //min.operator>(max) { min=*this; max=d; flag=-1; } int day=0; while (min<max) //min.operator<(max) { ++day; ++min; //min.operator++() } return day*flag; } void printDate() { cout<<_year<<"-"<<_month<<"-"<<_day<<endl; } private: int _year; int _month; int _day; }; void test() { Date d(2020,10,1); d.printDate(); d+=10; d.printDate(); d+=22; d.printDate(); d+=68; d.printDate(); d+=3650; d.printDate(); d+=-100; d.printDate(); d-=-100; d.printDate(); } void test2() { Date d(2020,10,17); --d; d.printDate(); Date d2(2020,10,17); Date d3=d2--; d.printDate(); } int main() { test2(); system("pause"); return 0; } void test1() { Date d1(2020,10,14); Date d2=d1;//调用拷贝构造-->用已经存在的对象创建新的对象 d2=d1;//调用赋值-->用已经存在的对象取修改另一个已经存在的对象内容 }
最新回复(0)