1 拷贝构造和运算符重载
1.1 拷贝构造
拷贝构造函数:对已存在的对象进行复制,构造一个新的对象
特性:
- 拷贝构造函数是构造函数的一个重载形式
- 拷贝构造函数有且仅有一个参数且为该类引用
- 如果不显示写,编译器会自动生成一个默认拷贝构造函数,默认的拷贝构造函数内置类型按字节顺序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝,对于自定义类型会调用它的拷贝构造
拷贝构造函数典型调用场景:
- 使用已存在对象创建新对象
- 函数参数类型为类类型对象
- 函数返回值类型为类类型对象
注意:在传参时能用引用尽量用引用,否则很消耗资源
1.1.1 深浅拷贝
浅拷贝:对于指针类型,复制对象时仅复制指针的值,使源对象和目标对象的指针指向同一块内存
深拷贝:复制对象时不仅复制指针,还复制指针所指向的内存(资源),使得源对象和目标对象各自拥有独立的内存块
在对象需要管理分配动态内存时,需要程序员自己实现深拷贝,否则编译器生成的默认构造就足够了
1.2 运算符重载
C++只能重载已有的运算符
-
可以重载
+ - * / % ^ & | ~ = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= ! && || ++ -- , ->* -> () [] new new[] delete delete[]
-
不可以重载
. .* :: ?: sizeof typeid static_cast dynamic_cast const_cast reinterpret_cast
-
不能改变运算符的优先级、结合性以及操作个数
-
不能创造新的操作符
运算符重载的形式:oprator
关键字 + 要重载的运算符
//单操作数:一个参数
T& oprator<op>(const T& x);
//双操作数:两个参数
T& operator<op>(const T& l,const T& r);
//以上返回类型的&以及参数const要根据实际而定
运算符重载既可以重载为成员函数,也可以定义重载为全局函数
特别的,成员函数由于this
指针的存在运算符重载函数的第一个参数始终为this
指针
1.2.1 赋值运算符重载
特性:
- 必须重载成类成员函数
- 没显示写,编译器会自动生成一个默认的赋值运算符重载函数
- 与拷贝构造类似,默认的只是浅拷贝,涉及资源管理需要程序员自己实现深拷贝
注意:
//构造对象时拷贝构造 已经存在则是赋值重载
vector<int> a;
vector<int> b = a;//拷贝构造
vector<int> c;
c = a;//复制运算符重载
1.3 日期类
Date.h文件
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <ostream>
using namespace std;
//日期类
class Date {
public:
//流插入流提取重载的友元函数
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);
Date(int _year = 0, int _month = 0, int _day = 0);
//获得对应年份中某月的天数
int GetMonthDays(int year, int month) {
static int days[13] = { -1, 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 days[month];
}
//对于比较运算符的重载
bool operator>(const Date& d) const;
bool operator>=(const Date& d) const;
bool operator<(const Date& d) const;
bool operator<=(const Date& d) const;
bool operator==(const Date& d) const;
bool operator!=(const Date& d) const;
//日期加减天数
Date& operator+=(const int day);
Date operator+(const int day) const;
Date& operator-=(const int day);
Date operator-(const int day) const;
//日期减日期
int operator-(const Date& d)const;
Date operator++(int);//后置加加
Date& operator++();
Date operator--(int);//后置减减
Date& operator--();
private:
int _year;
int _month;
int _day;
};
Date.cpp文件
#include "date.h"
Date::Date(int year, int month, int day) {
_year = year;
_month = month;
_day = day;
}
bool Date::operator>(const Date& d) const {
if (_year > d._year) {
return true;
}
else if (_year == d._year) {
if (_month > d._month) {
return true;
}
else if (_month == d._month) {
return _day > d._day;
}
}
return false;
}
bool Date::operator>=(const Date& d) const {
return !(*this < d);
}
bool Date::operator<(const Date& d) const {
return !(*this == d || *this > d);
}
bool Date::operator<=(const Date& d)const {
return !(*this > d);
}
bool Date::operator==(const Date& d)const {
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
bool Date::operator!=(const Date& d)const {
return !(*this == d);
}
//日期加等天数
Date& Date::operator+=(const int day) {
if (day < 0) {
return *this += -day;
}
_day += day;
while (_day > GetMonthDays(_year, _month)) {
_day -= GetMonthDays(_year, _month);
++_month;
if (_month == 13) {
++_year;
_month = 1;
}
}
return *this;
}
//日期加天数
Date Date::operator+(const int day)const {
Date tmp = *this;
return tmp += day;
}
//日期减等天数
Date& Date::operator-=(const int day) {
if (day < 0) {
return *this += -day;
}
_day -= day;
while (_day <= 0) {
--_month;
if (_month == 0) {
--_year;
_month = 12;
}
_day += GetMonthDays(_year, _month);
}
return *this;
}
//日期减天数
Date Date::operator-(const int day)const {
Date tmp = *this;
return tmp -= day;
}
//日期减日期
int Date::operator-(const Date& d)const {
Date max = *this;
Date min = d;
int flag = 1;
if (max < min) {
max = d;
min = *this;
flag = -1;
}
int days = 0;
while (max != min) {
++min;
++days;
}
return days * flag;
}
//后置加加
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;
}
//前置减减
Date& Date::operator--() {
*this -= 1;
return *this;
}
//重载流插入
ostream& operator<<(ostream& out, const Date& d) {
out << d._year << "年" << d._month << "月" << d._day << "日";
return out;
}
//重载流提取
istream& operator>>(istream& in, Date& d) {
cout << "请依次输入年月日:>";
in >> d._year >> d._month >> d._day;
return in;
}