拷贝构造(详解)

一、拷贝构造函数

拷贝构造函数,就像他的名字一样,使来拷贝的,他的作用是把一个已经存在的对象进行拷贝后,用拷贝来的值进行给其他对象赋值和作为返回值和参数等。

一、拷贝构造函数调用时机

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:拷贝构造的参数是引用类型

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数。
  • 复制对象,并从函数返回这个对象。

下面我们来看一个拷贝构造函数的例子:

cpp 复制代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class person {
public:
    int age;
    person() {
    
        cout << "调用无参构造" << endl;
    
    }
    person(int age) {
        this->age = age;
        cout << "调用有参构造" << endl;
    
    
    }
    person(const person&other) {
    
        cout << "调用拷贝构造" << endl;
        this->age = other.age;
    
    }
    ~person() {
    
        cout << "调用析构函数" << endl;
    
    }

};
void fun(person other) {
//参数以值的形式传递的时后掉用拷贝构造,不能是引用

}
person fun() {
    person p;
    return p;
}
void t1() {
    person p;
    person p1 = p;//用已经存在的对象初始化新对象隐式调用
    person p2;
    p2 = p;//不调用拷贝构造,这是赋值过程

}
void t2() {
    person p;
    fun(p);

}
void t3() {
    fun();
}
int main() {
    t3();
    return 0;
}

二、深拷贝浅拷贝

说到拷贝构造函数就不得不提到深拷贝浅拷贝的概念

深拷贝:对对象进行全面的复制,重新的创建堆区内存,把原对象中的数据复制到新地址中。

浅拷贝:简单的赋值过程,只是将内存的地址赋值给另一个变量,不重新申请内存空间,这样就出现了一个问题,就是在释放内存时会出现同一块内存被释放两次的情况。

|----------------|----------------------------------------|
| 地址存储变量1=地址1123 | 析构将内存归还操作系统 |
| 内存1123 | 内存1123被释放 |
| 地址存储变量2=地址1123 | 此对象析构函数也要调释放内存1123但是此内存已经归还操作系统找不到了,报错 |

下面我们来看深拷贝和浅拷贝的例子:

浅拷贝

cpp 复制代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class person {
public:
    int age;
    int* p;
    person() {
    
        cout << "调用无参构造" << endl;
        age = 0;
        p = nullptr;

    }
    person(int age) {
        this->age = age;
        this->p = new int[age];
        for (int i = 0;i < age;i++) {
            p[i] = i;
        
        
        }
        cout << "调用有参构造" << endl;
    
    
    }
    person(const person&other) {
    
        cout << "调用拷贝构造" << endl;
        this->age = other.age;
        this->p = other.p;//浅拷贝;两个对象中的成员指针变量指向同一块地址
        //此代码运行会有错误,析构函数会非法访问
    }
    ~person() {
    
        cout << "调用析构函数" << endl;
    
    }

};
void fun(person p) {
//参数以值的形式传递的时后掉用拷贝构造,不能是引用

}
person fun() {
    person p;
    return p;

}
void t1() {
    person p;
    person p1 = p;//隐式调用
    person p2;
    p2 = p;//不调用拷贝构造,这是赋值过程


}
void t2() {

    person p;
    fun(p);//实参初始化形参调用

}
void t3() {

    fun();

}
int main() {
    t3();



    return 0;
}

深拷贝

cpp 复制代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class person {
public:
    int age;
    int* p;
    person() {
    
        cout << "调用无参构造" << endl;
        age = 0;
        p = nullptr;

    }
    person(int age) {
        this->age = age;
        this->p = new int[age];
        for (int i = 0;i < age;i++) {
            p[i] = i;
        
        
        }
        cout << "调用有参构造" << endl;
    
    
    }
    person(const person&other) {
    
        cout << "调用拷贝构造" << endl;
        this->age = other.age;
        //深拷贝:指向的内存地址不同但是内容大小相同
        this->p = new int[age];//大小一样
        for (int i = 0;i < age;i++) {//内容一样
            this->p[i] = other.p[i];
        
        
        }
    }
    ~person() {
    
        cout << "调用析构函数" << endl;
    
    }

};
void fun(person p) {
//参数以值的形式传递的时后掉用拷贝构造,不能是引用

}
person fun() {
    person p;
    return p;

}
void t1() {
    person p;
    person p1 = p;//隐式调用
    person p2;
    p2 = p;//不调用拷贝构造,这是赋值过程


}
void t2() {

    person p;
    fun(p);//实参初始化形参调用

}
void t3() {

    fun();

}
int main() {
    t3();



    return 0;
}
相关推荐
岁忧1 小时前
(nice!!!)(LeetCode 每日一题) 679. 24 点游戏 (深度优先搜索)
java·c++·leetcode·游戏·go·深度优先
小欣加油1 小时前
leetcode 3 无重复字符的最长子串
c++·算法·leetcode
四维碎片3 小时前
【Qt】线程池与全局信号实现异步协作
开发语言·qt·ui·visual studio
IT码农-爱吃辣条3 小时前
Three.js 初级教程大全
开发语言·javascript·three.js
☺����3 小时前
实现自己的AI视频监控系统-第一章-视频拉流与解码2
开发语言·人工智能·python·音视频
zylyehuo3 小时前
C++基础编程
c++
染翰4 小时前
lua入门以及在Redis中的应用
开发语言·redis·lua
王者鳜錸4 小时前
PYTHON让繁琐的工作自动化-函数
开发语言·python·自动化
兔老大RabbitMQ4 小时前
git pull origin master失败
java·开发语言·git
tt5555555555555 小时前
C/C++嵌入式笔试核心考点精解
c语言·开发语言·c++