C++类与对象part1
目录
1.类的6个默认函数
2.构造函数(相当于init)
3.析构函数 (相当于destroy)
4.拷贝构造函数
赋值运算符重载
运算符重载
赋值运算符重载
引入:
你知道为什么cout可以自动识别类型吗?
其实cout是一个类
自动识别类型是运算符重载和函数重载的双重效果
如果是自定义类型的,就自己写
例:
但是就会变成这样
怎么解决?
如果想要连续<<(cout<<x1<<x2)
注意它的结合性是左结合,要求它的返回值为ostream
同理:
正文开始!
1.类的6个默认函数
2.构造函数(相当于init)
其中,无返回值并不是说为void,而是什么都不用写。
可以重载:一个类可以有多个构造函数。
注意在有参和无参的情况下的写法分别如下:
(无参的不给括号,给括号反而会报错)
原因如下:
区分不清是在声明还是定义对象
3.析构函数 (相当于destroy)
‘~’有按位取反的感觉,功能和构造函数是相反的
(1.无参的 2.全缺省的 3.编译器自动生成的)
例:
4.拷贝构造函数
例:
但是这样使用会报错哦
拷贝构造的写法:
例:
倒计时的实现:
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 拷贝构造// Date d2(d1);Date(const Date& d){cout << "Date(Date& d)" << endl;_year = d._year;_month = d._month;_day = d._day;/*d._year = _year;d._month = _month;d._day = _day;*/}int GetMonthDay(int year, int month){assert(month > 0 && month < 13);int monthArray[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 monthArray[month];}}
// +Date Add(int x){Date tmp = *this;tmp._day += x;while (tmp._day > GetMonthDay(tmp._year, tmp._month)){// 进位tmp._day -= GetMonthDay(tmp._year, tmp._month);++tmp._month;if (tmp._month == 13){tmp._year++;tmp._month = 1;}}return tmp;}// +=Date& AddEqual(int x){_day += x;while (_day > GetMonthDay(_year, _month)){// 进位_day -= GetMonthDay(_year, _month);++_month;if (_month == 13){_year++;_month = 1;}}return *this;}void Print(){//cout << _year << "/" << _month << "/" << _day << endl;cout << _year << "年" << _month << "月" << _day << "日" << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 2, 3);Date d2 = d1.Add(100);Date d3 = d1.Add(150);d1.Print();d2.Print();d3.Print();d1.AddEqual(200);d1.Print();// 实现一个函数,获取多少以后的一个日期return 0;
}
注意
浅拷贝时(默认的拷贝被称为值拷贝/浅拷贝),在栈中:(会出现问题)
例:
(数据可覆盖)
而深拷贝则会另开空间
赋值运算符重载
运算符重载
与函数重载并没有关系
操作时:
第一个参数是左操作数,第二个参数是右操作数
例:
(但是类中的成员在private里,没有办法访问怎么办?不要着急,这个问题的解答见下文)
注意:
C++中,<<还是流插入运算符,优先级高于==,所以一定得加上(),才能保证调用了operator运算符重载
解答:但是类中的成员在private里,没有办法访问怎么办?
1:调用getyear、getmonth、getday等等函数调用
2:直接放在类里面不就好了
但是注意:
在类里就只有一个操作数了,避免报错(有多个参数)
正确写法:
d1:this
d2:d
补充:小于的return简化
补充:如果在前面就写过了<和=的运算符重载,现在想要写<=的,可以进行如下简化
类似的如下:
注意:
(.* 不能重载(不是*))
赋值运算符重载
会调用拷贝构造函数,再==
例:
注意:
转化成调用函数不是说在预处理阶段把代码改了,是编译时编译器识别,看有没有实现赋值,实现赋值就转化成call
对于连续赋值的情况如何解决?
加返回值
那拷贝构造和赋值运算符重载怎么区分呢?
赋值运算符重载的对象是已经创建好的对象
例: