拷贝构造(详解)

一、拷贝构造函数

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

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

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

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

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

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;
}
相关推荐
小成202303202654 小时前
C++~07补充
开发语言·c++
hold?fish:palm4 小时前
40 二叉树的直径
c++·leetcode
解决小子4 小时前
【虚幻引擎】【C++】【GAS框架】构建角色基类、属性集、数值钳制
c++·笔记·游戏引擎·虚幻·gas·能力系统
lunar_coder6 小时前
【C++】如何解决智能指针的析构函数,如何实现shared_ptr的引用计数以及解决shared_ptr的循环引用
c++·1024程序员节
白白白小纯6 小时前
C++进阶.多态
c++
2401_885885047 小时前
国际语音C#接口怎么写?.NET环境下实现国际语音验证码批量下发
开发语言·c#·.net
程序猿乐锅7 小时前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
Wang's Blog7 小时前
Java 项目实战: 交友项目 - 查询圈子个人动态:查询我的动态需求分析
java·开发语言·交友
凯瑟琳.奥古斯特7 小时前
力扣1016高效解法:剪枝优化技巧
开发语言·c++·算法·leetcode·职场和发展