C++拷贝构造函数和运算符重载--4

简介: C++拷贝构造函数和运算符重载--4

C++拷贝构造函数和运算符重载--3 https://developer.aliyun.com/article/1424591

(3)“ 前置++,后置++,前置--,后置-- ”在类对象内定义进行演示和解说。


 

// 后置++,形参为int,C++专门规定,为了与前置++区分
    Date operator++(int) {
        Date ret(*this);
        *this += 1;
        return ret;
    }
    // 前置++
    Date& operator++() {
        *this += 1;
        return *this;
    }
    // 后置--,形参为int,C++专门规定,为了与前置--区分
    Date operator--(int) {
      //先将原本类进行拷贝,然后将此对象里的值--,返回此对象,实现了先赋值,再--
        Date ret(*this);
        *this -= 1;
        return ret;
    }
    // 前置--
    Date& operator--() {
      //直接返回*this,实现了先把对象的值--,然后将此对象返回,实现了先--,再赋值
        *this -= 1;
        return *this;
    }

       这里要注意的是前置++、前置--和后置++、后置--的写法和前置和后置的实现。如上代码中C++的专门规定前置与后置的写法,前置的实现是先进行运算,然后再进行赋值,所以要直接用this进行。后置的实现要先进行赋值,然后再运算。这里我们虽然实现了this的运算,但返回的是运算前的对象,进而实现了此原理。


       (4)赋值运算符。赋值运算符比较特殊,我们要区分它与拷贝构造。当类与类进行赋值时,若类还没有进行初始化,将会调用拷贝构造;若已进行了初始化,将会调用赋值运算符。


       1,赋值运算符一般也要设置返回类型,一般返回 *this,因为我们要保证连续赋值的情况。


#include <iostream>
#include <assert.h>
using namespace std;
class Date
{
public:
  Date(int year = 1900, int month = 1, int day = 1)
  {
  _year = year;
  _month = month;
  _day = day;
  }
  // 赋值运算符重载
  Date& operator=(const Date& d)
  {
  _year = d._year;
  _month = d._month;
  _day = d._day;
  return *this;
  }
private:
  int _year;
  int _month;
  int _day;
};
int main()
{
  Date d1(2023, 11, 9);
  Date d2, d3, d4;
  d4 = d3 = d2 = d1;//调用赋值运算符重载
  return 0;
}


       2,赋值运算符只能重载成类的成员函数不能重载成全局函数。


class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    int _year;
    int _month;
    int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)//出现错误,出现在全局中
{
    left._year = right._year;
    left._month = right._month;
    left._day = right._day;
    return left;
}


       原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现 一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,因此,赋值运算符重载只能是类的成员函数。


       3,用户自己如果没有定义赋值运算符,编译器会生成一个默认赋值运算符重载,以浅拷贝的形式实现拷贝。内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。


#include <iostream>
using namespace std;
class Time
{
public:
  Time()
  {
  _hour = 1;
  _minute = 1;
  _second = 1;
  }
  Time& operator=(const Time& t)
  {  
  _hour = t._hour;
  _minute = t._minute;
  _second = t._second;
  return *this;
  }
private:
  int _hour;
  int _minute;
  int _second;
};
class Date
{
private:
  // 基本类型(内置类型)
  int _year = 1970;
  int _month = 1;
  int _day = 1;
  // 自定义类型
  Time _t;
};
int main()
{
  Date d1;
  Date d2;
  d1 = d2;
  return 0;
}


d1 = d2运行的调试解图

646584d2a3a94989a9a86b9724d10244.png



       默认赋值运算符重载的原理跟默认拷贝构造一样,如果类中未涉及到资源空间的管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要自己定义实现。


       (5)流操作符的重载。在C++程序中,我们也可实现插入操作符(<<)和提取操作符(>>)的重载。


       我们首先要认识ostream和istream。ostream用于处理输出流的类,类中定义了插入操作符(<<)来将数据写入输出流;istream是用于处理输入流的类。它定义了提取操作符(>>)来从输入流中提取数据。


定义样例:


在类的内部定义

第一个参数默认this指针
class Date
{
private:
    int _year = 2023;
    int _month = 10;
    int _day = 16;
};
//没有返回类型的情况
void operator<<(ostream& out);
void operator>>(istream& in);
//在类内部声明,在外部进行定义,也相当于在内部定义
void Date::operator<<(ostream& out);
void Date::operator>>(istream& in);
//返回类型为ostream和istream,这种情况为了支持连续输入输出的情况,因为连续输入输出需要有返回值去接收
ostream& operator<<(ostream& out);
istream& operator>>(istream& in);


在类的外部定义


没有默认参数,需要把类写入形参中
class Date
{
private:
    int _year = 2023;
    int _month = 10;
    int _day = 16;
};
//没有返回类型的情况
void operator<<(ostream& out, const Date& d1);
void operator>>(istream& out, const Date& d1);
//返回类型为ostream和istream,这种情况为了支持连续输入输出的情况,因为连续输入输出需要有返回值去接收
ostream& operator<<(ostream& out, const Date& d1);
istream& operator>>(istream& out, const Date& d1);


C++拷贝构造函数和运算符重载--5https://developer.aliyun.com/article/1424609?spm=a2c6h.13148508.setting.28.214f4f0emw3QR7

相关文章
|
1天前
|
测试技术 C++
C++|运算符重载(3)|日期类的计算
C++|运算符重载(3)|日期类的计算
|
1天前
|
C语言 C++
C++|运算符重载(2)|运算符重载的方法与规则
C++|运算符重载(2)|运算符重载的方法与规则
|
2天前
|
编译器 C++
C++|运算符重载(1)|为什么要进行运算符重载
C++|运算符重载(1)|为什么要进行运算符重载
|
3天前
|
编译器 C语言 C++
【C++从练气到飞升】05---运算符重载(二)
【C++从练气到飞升】05---运算符重载(二)
|
3天前
|
编译器 C++
【C++从练气到飞升】05---运算符重载(一)
【C++从练气到飞升】05---运算符重载(一)
|
3天前
|
存储 编译器 C++
【C++从练气到飞升】04---拷贝构造函数
【C++从练气到飞升】04---拷贝构造函数
|
3天前
|
编译器 C++
【C++】类与对象(运算符重载、const成员、取地址重载)
【C++】类与对象(运算符重载、const成员、取地址重载)
14 2
|
3天前
|
存储 编译器 对象存储
【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)
【C++】类与对象(构造函数、析构函数、拷贝构造函数、常引用)
7 0
|
3天前
|
编译器 C++ 索引
【C++类和对象】拷贝构造与赋值运算符重载(下)
【C++类和对象】拷贝构造与赋值运算符重载
|
3天前
|
存储 编译器 C++
【C++类和对象】拷贝构造与赋值运算符重载(上)
【C++类和对象】拷贝构造与赋值运算符重载