拷贝构造(详解)

一、拷贝构造函数

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

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

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

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

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

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;
}
相关推荐
IvanCodes17 分钟前
Python 基础语法(七):推导式与常见遍历写法
开发语言·python
暮雨哀尘19 分钟前
Java 基础练习(一):创建类并调用对象
java·开发语言
zhangzeyuaaa39 分钟前
Python requests:raise_for_status() 与 4xx/5xx 异常层次详解
开发语言·python
泡海椒1 小时前
动态代理核心原理:JQuick-Java接口规则自动生成机制解析
java·开发语言·python
shirsl1 小时前
算法 Day 2 滑动窗口 + 栈 / 单调栈
开发语言·python·算法
菜鸟~noob2331 小时前
【电子战】第08篇:多普勒测向的工程实现与优化【含matlab代码】
开发语言·matlab
菜鸟~noob2331 小时前
【电子战】第06篇:干涉仪与相位差测向【含matlab代码】
开发语言·matlab
老王爱玩车1 小时前
深入理解指针2
c语言·开发语言·学习
quantdash_cc1 小时前
股票历史数据为什么比实时行情更重要?回测结果失真的根源可能就在 K 线数据
开发语言·python·数据分析·量化交易·股票数据·quantdash
光电的一只菜鸡2 小时前
为什么调整LSC会对AF产生影响
android·开发语言·kotlin