C++拷贝构造函数

拷贝构造函数

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

拷贝构造函数还在另二个方面使用:

1.当函数的形参是类的对象, 调用函数时, 进行形参与实参结合时使用。这时要在内存新建立一个局部对象, 并把实参拷贝到新的对象空间

中。

2.当函数的返回值是类对象, 函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。因为局部对象在离开建立

它的函数时就消亡了,不可能在返回调用函数后继续生存,所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对

象,该临时对象的生存周期只在函数调用处的表达式中。所谓return对象, 实际上是调用拷贝构造函数把该对象的值拷入临时对象空间。如果

返回的是变量, 处理过程类似,只是不调用构造函数。

2.拷贝构造函数的形参类型一定是引用类型,否则将引起无穷构造过程!!!

class Object
{
private:
	int value;
	float price;
public:
	Object() {}  //缺省构造函数
	Object(int val = 0, float ft = 0.0) :value(val), price(ft) {}//自定义构造函数    列表
	Object(const Object& c) {}   //拷贝构造函数
	~Object() {};    //析构函数
};

只有构造函数和拷贝构造函数可以用列表方式初始化,因为对象只能被构建一次,其成员变量也只能构建一次

如果不想对象被拷贝或者赋值,将拷贝构造函数和赋值函数设置为私有并且delect,外部就无法拷贝和赋值

class SeqList
{
    private:
	int data[SEQ_ INIT_ SIZE];
	int maxsize;
	int cursize;
	SeqList (const SeqList& seq) = delete; // cl1
	SeqList& operator=(const SeqList& seq) = delete; // C11
    public:
    SwqList() {}

};
int main()
{
    SeqList seqa;
	SeqList seqb (sega) ;//error
	SeqList seqc;
	seqc=seqb;       //error
    return 0;
}

深拷贝和浅拷贝

浅拷贝 (影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用.

深拷贝 (深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.

浅拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到

目标对象。
类的成员变量中如果包含指针或者文件指针,如果使用默认拷贝构造函数和默认赋值函数可能会出现重复释放内存和内存泄漏(浅拷贝)

所以需要自己设计拷贝构造函数和赋值函数**(深拷贝)**

class SeqList
{
    int* data;
	int maxsize;
	int cursize;
public:
	SeqList():data (NULL),maxsize(SEQ_INIT_SIZE), cursize(0)
	{ data = (int*)malloc(sizeof(int) * maxsize); }
    
	~SeqList()
	{ 
         free (data) ;
		data = NULL;
    }
    
	SeqList (const SeqList& seq)//浅拷贝
	{
		data = seq. data;
		maxsize = seq. maxsize; 
         cursize = seq. cursize ;
    }
	SeqList& operator= (const SeqList& seq)//赋值
	{
		if (this != &seq)
        {
             data = seq. data;
			maxsize = seq. maxsize;
             cursize = seq. cursize; 
        }
		return *this;
    }
};
int main()
{
	SeqList seqa;
	SeqList seqb;
    
	seqb = seqa;//改写了seqa data指针的指向到seqb的申请的空间,程序结束时会释放两遍seqb申请的空间,并且seqa申请的空间没有被释放,内存泄漏
	return 0;
}

改写后

class SeqList
{
    int* data;
	int maxsize;
	int cursize;
public:
	SeqList():data (NULL),maxsize(SEQ_INIT_SIZE), cursize(0)
	{ data = (int*)malloc(sizeof(int) * maxsize); }
    
	~SeqList()
	{ 
         free (data) ;
		data = NULL;
    }
    
	SeqList (const SeqList& seq)//深拷贝
	{
		data = (int*)malloc(sizeof(int) * seq. maxsize) ;
		memcpy (data,seq.data,sizeof(int) * seq. cursize) ;

		maxsize = seq. maxsize; 
         cursize = seq. cursize ;
    }
	SeqList& operator= (const SeqList& seq)//赋值
	{
		if (this != &seq)
        {
             free(data);//先释放原有的空间
             data = (int*)malloc(sizeof(int) * seq. maxsize) ;
             memcpy (data,seq.data,sizeof(int) * seq. cursize) ;
            
			maxsize = seq. maxsize; 
             cursize = seq. cursize; 
        }
		return *this;
    }
};
int main()
{
	SeqList seqa;
	SeqList seqb;
    seqa.SeqList(seqb);
    seqb = seqa;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小新 蜡笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值