【C++类和对象】拷贝构造、运算符重载以及日期类的实现

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;
}
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿辉不一般

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值