拷贝构造

构造函数的基本形式

拷贝构造函数的本质也是一个构造函数,一个对象给另一个对象进行初始化的时候,就会调用拷贝构造。话不多说,先上代码:

#include <iostream>

using namespace std;

class Example
{
public:
    static int i;

    Example()
    {
        cout << "constructor runs" << endl;
    }

    Example(const Example &a) //拷贝构造函数的形式
    {
        i++;
        cout << "copy constructor has run " << i << " time" << endl;
    }
};

int Example::i = 0;

int main()
{

    Example c;

    Example c1(c); //对象传参
    Example c2 = c1; //对象赋值
    Example c3 = Example(c1); //临时对象+赋值
    Example *c4 = new Example(c1); //指针对象
    delete c4;
    Example(c5); //临时对象
    return 0;
}

运行结果如下:
在这里插入图片描述
由此可见,运行拷贝构造,某种意义上是一种构造函数的重载形式,其本身也可以重载。通过对象产生新的对象时,会调用拷贝构造函数。**单独创建临时对象仅仅调用构造函数。**构造函数与拷贝构造只会运行一个,并且已经声明的对象相互赋值不会触发构造函数和拷贝构造。所以,除了我们重写的拷贝构造函数,默认构造函数的作用就是将新生成的对象成员逐个以传递的对象成员进行赋值。

Example(const Example &a)
{
	this->character1 = a.character1;
	this->character2 = a.character2; //默认的拷贝构造形式,浅拷贝
}

请记住:函数的返回值如果是一个对象,会运行拷贝构造。如果函数参数列表中有对象的实参,也会运行拷贝构造。!!!

深拷贝

关于拷贝构造存在一类危险情况。当成员中含有指针的时候,避免通过默认拷贝构造进行赋值,请按照上文的形式重写拷贝构造函数,从而进行深拷贝。例如在对类似string类型赋值的时候,使用内存拷贝的方式进行赋值。

代码如下:

#include <iostream>
#include <cstring>

using namespace std;

class Example
{
public:
    int* a;
    Example()
    {
        a = new int[2];
        a[0] = 1;
        a[1] = 1;
        cout << ("constructor runs, now a[] = {1,1}") << endl;
    }

    Example(const Example &c) //重写拷贝构造
    {
        this->a = new int[sizeof(c.a)];
        memcpy(c.a, this->a, (int)sizeof(c.a));
        cout << ("copy constructor runs, now c2.a[] = {1,1}") << endl;
    }

    ~Example()
    {
        delete[] a;
    }
};

int main()
{
    Example c1;
    Example c2 = c1;
    return 0;
}

运行结果:
在这里插入图片描述
如果此处不进行深拷贝的话,很容易理解当delete[] 运行到第二次的时候,释放的是一个野指针,内存一定会崩溃。
顺带一提,构造与析构执行顺序:c1 构造-> c2拷贝 -> c1析构 -> c2析构。

作为函数参数时,可以尽可能避免产生临时对象,可以采用传引用传地址的方法,避免重写深拷贝函数带来的麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值