c++拷贝构造函数笔记和总结

16 篇文章 1 订阅

以下内容牵扯到了一点点计数器的知识!

什么是拷贝构造函数

是区别于不同类型的对象来说的一种复制,相同类型的类对象是通过拷贝构造来进行复制的。简单来说,系统会分配另一个内存呢来完成copy!

拷贝构造函数的调用

1.当调用函数的参数为类的对象
#include<iostream>
using namespace std;
class CExample
{
private:
    int a;
public:
    CExample(int b)
    {
        a=b;
        printf("constructor is called\n");
    }
    CExample(const CExample & c)
    {
        a=c.a;
        printf("copy constructor is called\n");
    }
    ~CExample()
    {
     cout<<"destructor is called\n";
    }
    void Show()
    {
     cout<<a<<endl;
    }
};
void g_fun(CExample c)
{
    cout<<"g_func"<<endl;
}
int main()
{
    CExample A(100);
    CExample B=A;
    B.Show(); 
    g_fun(A);
    return 0;
}

在main函数调用g_fun()时,会发生的几个步骤:
** 1.A对象传入形参时,会先产生一个临时变量C
2.之后,会调用拷贝构造函数把A的值给C,这俩步骤类似于:CExample C(A);
3.g_fun()执行完之后,就会析构雕对象C;**

运行结果:
constructor is called
copy constructor is called
100
copy constructor is called
g_func()
destructor is called
destructor is called
destructor is called

2.函数的返回值为类:
#include<iostream>
using namespace std;
class CExample
{
private:
    int a;
public:
    //构造函数
    CExample(int b)
    {
     a=b;
        printf("constructor is called\n");
    }
    //拷贝构造函数
    CExample(const CExample & c)
    {
     a=c.a;
        printf("copy constructor is called\n");
    }
    //析构函数
    ~CExample()
    {
     cout<<"destructor is called\n";
    }
    void Show()
    {
     cout<<a<<endl;
    }
};
CExample g_fun()
{
    CExample temp(0);
    return temp;
}
int main()
{
    
    g_fun();
    return 0;
}

在g_fun()函数执行到return时,产生的几个步骤:
** 1.首先会产生一个临时变量T
2.然后调用拷贝构造函数把temp的值给T,这俩步骤类似于 CExample T(temp);
3.因为temp是局部变量,所以在函数执行到对后时,先析构temp
4整个g_fun()函数都执行结束后,再析构T**

深拷贝和浅拷贝

总的前提:在出现类的等号赋值时,就会出现拷贝!在用户没有定义拷贝构造函数的时候,系统会有一个默认的拷贝函数——浅拷贝
当数据中有指针时,如果采用浅拷贝,俩个类的俩个指针都会指向同一个地址,当对象快death时会调用俩次析构函数,导致指针悬垂
而深拷贝可以在堆内存中另外申请空间来储存数据,从而解决指针悬垂!有指针,必须深拷贝

深拷贝:
#include<iostream>
#include<assert.h>
using namespace std;
class Rect
{
public:
    Rect()
    {
     p=new int(100);
    }
    
    Rect(const Rect& r)
    {
     width=r.width;
        height=r.height;
     p=new int(100);
        *p=*(r.p);
    }
     
    ~Rect()
    {
     assert(p!=NULL);
        delete p;
    }
private:
    int width;
    int height;
    int *p;
};
int main()
{
    Rect rect1;
    Rect rect2(rect1);
    return 0;
}

深拷贝需要重新动态分配空间

tips:

我们发现对象的复制大多在进行“值传递”时发生,这里有一个小技巧可以防止按值传递——**声明一个私有拷贝构造函数。**甚至不必去定义这个拷贝构造函数,这样因为拷贝构造函数是私有的,如果用户试图按值传递或函数返回该类对象,将得到一个编译错误,从而可以避免按值传递或返回对象。

参考bolg:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值