小工具知识网

当前位置: 首页 > 行业知识 > 【C++】:拷贝构造函数和赋值运算符重载

行业知识

【C++】:拷贝构造函数和赋值运算符重载

2026-11-09 22:40:52 来源:互联网转载

目录

  • 一,拷贝构造函数
    • 1. 什么是拷贝构造函数
    • 2. 拷贝构造函数的特性
    • 3. 实践总结
    • 二,赋值运算符重载
      • 2.1 运算符重载
      • 2.2 赋值运算符重载

        一,拷贝构造函数

        1. 什么是拷贝构造函数

        拷贝构造函数是特殊的构造函数。是用一个已经存在的对象,赋值拷贝给另一个新创建的已经存在的对象。

        本质:用同类型的对象拷贝初始化。

        2. 拷贝构造函数的特性

        拷贝构造函数也是特殊的成员函数,其特征如下:

        2.1 拷贝构造函数是构造函数的一个重载形式。

        2.2 拷贝构造函数的函数名域类名相同,参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为在语法上引发无穷递归调用。

        注意:

        • Date d2(d1); 这句代码也等价于Date d2 = d1;也是拷贝构造的写法。
          #include using namespace std;class Date{public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}//拷贝构造函数//参数只有一个,必须是类类型对象的引用。    //Date d2(d1); Date(Date& d)   //传引用,正确写法//Date(Date d)  //传值,错误写法{    //用来检测是否调用该拷贝构造函数cout cout Date d1(2024,4,21);d1.Print();//d2对象不在按指定年月日初始化,而是想和d1对象初始化一样//拷贝构造:用同类型的对象拷贝初始化Date d2(d1);//这句代码也等价于Date d2 = d1;也是拷贝构造的写法d2.Print();return 0;}public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}Date(Date& d)  {    //用来检测是否调用该拷贝构造函数cout cout d.Print();}int main(){Date d1(2024, 4, 12);//调用func之前会先进入拷贝构造函数func(d1);return 0;}public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}Date(Date& d)  {    //用来检测是否调用该拷贝构造函数cout cout d-Print();}int main(){Date d1(2024, 4, 12);func(&d1);return 0;}public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}Date(Date& d)  {    //用来检测是否调用该拷贝构造函数cout cout d.Print();}int main(){Date d1(2024, 4, 12);//调用func之前会先进入拷贝构造函数func(d1);return 0;}public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}//用指针就不会形成无穷递归,但此时它就是一个普通构造了,不是拷贝构造。//感觉怪怪的,所以一般用引用Date(Date* d){    _year = d-_year;_month = d-_month;_day = d-_day;}void Print(){cout Date d2(2024, 4, 21);Date d3(&d2);d3.Print();return 0;}public:Time(){_hour = 1;_minute = 1;_second = 1;}Time(const Time& t){_hour = t._hour;_minute = t._minute;_second = t._second;//检测是否调用了这个拷贝构造函数cout public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout Date d1(2024, 4, 23);// 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数Date d2(d1);d2.Print();return 0;}public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}//注意:如果没有显示写析构函数,编译器也会自动生成。//自动生成的析构对内置类型不做处理,自定义类型才会去调用它的析构~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:DataType* _array;int _capacity;int _size;};int main(){Stack st1;st1.Push(1);st1.Push(1);st1.Push(1);Stack st2 = st1;return 0;}_array = (DataType*)malloc(sizeof(DataType) * st._capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}//开辟好空间后再把值拷贝进去memcpy(_array, st._array, sizeof(DataType) * st._size);_size = st._size;_capacity = st._capacity;}public:void func(){cout //成员函数要加&才能取到函数指针PtrFunc fp = &OB::func; //定义成员函数指针fp 指向函数funcOB tmp;//定义OB类对象tmp(tmp.*fp)(); //调用成员函数的指针return 0;}public:Date(int year , int month , int day ){_year = year;_month = month;_day = day;}//d3.operator== (d4)//d3传给了隐含的this指针,d是d4的别名 bool operator== (const Date & d) { return _year == d._year && _month == d._month && _day == d._day; }void Print(){cout Date d3(2024, 4, 12);Date d4(2024, 4, 15);//显式调用(一般不这样写)//cout public:Date(int year = 2024, int month = 4, int day = 21){_year = year;_month = month;_day = day;}//拷贝构造Date(const Date& d){cout //_year = d._year;//_month = d._month;//_day = d._day;//}//有时候会带返回值:目的是为了连续拷贝//d1 = d2 = d3; //比如这里,d是d3的别名,从右往左,先d2 = d3,返回值是d2Date& operator= (const Date& d){    //检测是否自己给自己赋值     if(this != &d)  {_year = d._year;_month = d._month;_day = d._day;  }              //这里的d2的地址是this ,*this就是d2。      //这里的*this才是对象本身,对象在main的作用域      //里创建的,因此出main作用域才会析构销毁,      //出了当前函数不会析构。所以可以用引用返回。return *this;}void Print(){cout Date d1(2024, 4, 12);//拷贝构造//一个已经存在的对象,拷贝给另一个要创建初始化的对象Date d2 = d1;Date d3(2024, 5, 1);//赋值拷贝/赋值重载//一个已经存在的对象,拷贝赋值给另一个已经存在的对象//d1 = d3;//连续赋值d1 = d2 = d3;return 0;}public: Date(int year, int minute, int day)   {      cout       cout       cout  Date temp(d);  return temp;  }  int main()  { Date d1(2022,1,13); Test(d1);  return 0;  }

上一篇:前端从普通登录到单点登录(SSO)

下一篇:服务器网卡怎么调速度的?