C++——深拷贝与浅拷贝

一、浅赋值问题

(1)如果类中叧包含简单数据成员,没有指向堆的指针, 可以使用编译器提供的默认复制构造函数

(2)如果类中包含指向堆中数据的指针,浅复制将出现 严重问题

①浅复制直接复制两个对象间的指针成员,导致两个指针 指向堆中同一坑内存区域

② 一个对象的修改将导致另一个对象的修改

③ 一个对象超出作用域,将导致内存释放,使得另一个对 象的指针无效,对其访问将导致程序异常。

二、编写自己的赋值构造函数(完成深复制的内容):实现了资源的重新分配

(1)含有指针成员的类,通常需要编写构造函数和复制 构造函数,同时需要实现相应的复制构造函数,以 及运算符重载

(2)实现“深复制”,创建对象备仹时,为新对象在堆 中分配自己的内存,并将现有值复制到新内存中。

在这里插入图片描述

Tricycle类举例:
第一部分:主函数:main.cpp

#include "Tricyle.h"
#include "iostream"
 
int main()
{
	Tricycle wichita;
   Tricycle dallas(wichita);   //复制构造函数
   wichita.setSpeed(10);
   std::cout<<"Wichita ";
   wichita.pedal();
 
    std::cout<<"Dallas ";
    dallas.pedal();
   std::cout<<"Wichita ";
  wichita.brake();
   std::cout<<"Dallas ";
     dallas.brake();
 
	return 0;
}

第二部分,头文件:Tricycle.h

#ifndef TRICYLE_H_INCLUDED
#define TRICYLE_H_INCLUDED
 
//defination class
class Tricycle 
{
public:
	Tricycle(); //constructor fun
	Tricycle(const Tricycle &rsh);//copy constructor fun
	~Tricycle(); //disconstructor fun
	int getSpeed()const{return *speed;}
	void setSpeed(int newSpeed){*speed = newSpeed;}
	void pedal(); //速度增加
	void brake();
private:
	int *speed;   //在堆中申请了内存
};
 
#endif

第三部分:Tricycle.cpp

 
#include "Tricyle.h"
#include "iostream"
using namespace std;
 
Tricycle::Tricycle()
{
	speed = new int(5);
 
}
Tricycle::Tricycle(const Tricycle &rsh)
{
	speed = new int ;  //申请动态空间,但是并没有进行初始化
	*speed = *rsh.speed;   //或者写成,*speed = rsh.getSpeed();
 
}
Tricycle::~Tricycle()
{
	delete speed;
	speed =NULL;
}
 
//速度增加
void Tricycle::pedal()
{
	(*speed)++;   //或者setSpeed(getSpeed()+1)
	std::cout << "pedaling" << getSpeed()<<'\n';
 
}
 
void Tricycle::brake()
{
	(*speed)--;
	std::cout << "brakeing" << getSpeed()<<'\n';
 
}

运行结果:

在这里插入图片描述

深复制的例子:Person类

#include <iostream>
#include <string>
using namespace std;
 
class Person 
{ 
public: 
	Person();                                 //缺省的构造函数                    
	Person(const char *name, int age, char sex);   //带参数构造函数
	Person(Person &p);                      //复制构造函数构造函数                             
	~Person();                              //析构函数
	void out()                             //输出信息
	{cout<<name<<","<<age<<","<<sex<<endl;}  
 
private:  
	char *name; 
	char sex;  
	int age; 
}; 
 
int main() 
{  
	cout << "***第一种情况,调用无参的构造函数"<<endl;;
	Person a;
	a.out();
	cout << "***第二种情况,调用含参的构造函数"<<endl;
	Person p1("zhangsan",20,'F');   //对构造函数进行初始化
	p1.out(); 
	cout << "***第三种情况,复制构造函数"<<endl;
	Person p2(p1); 
	p2.out(); 
 
	return 0; 
} 
 
Person::Person()
{
	cout << "\t 调用了无参数的构造函数:";
	name = new char[10];
	strcpy(name,"haoaowei");
	sex = 'M';
	age = 25;
 
}
 
//带参数构造函数
 
Person::Person(const char *name, int age, char sex)
{
	cout << "\t 调用了含参数的构造函数:";
	this->name = new char[strlen(name)+1];  //加1是为存储\0
	strcpy(this->name,name);
	this->age = age;
	this->sex = sex;
}
Person::~Person()
{
	cout << "name:"<<name<<"调用了析构函数"<< endl;
	delete []name;
	name = NULL;
}
 
//复制构造函数
Person::Person(Person &p)
{
	cout << "\t 调用了复制构造函数:";
	name = new char[strlen(p.name)+1];
	strcpy(name,p.name);
	this->age = p.age;
	this->sex = p.sex;
}

运行结果:
在这里插入图片描述


参考网址:
https://www.cnblogs.com/BlueTzar/articles/1223313.html https://www.cnblogs.com/xiaodingmu/p/7407307.html
https://blog.csdn.net/haoaoweitt/article/details/81204336(转载)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拷贝拷贝是两种不同的拷贝方式,用于复制对象。在C++中,当对含有指针成员的对象进行拷贝时,需要考虑使用拷贝来避免内存重复释放的问题。 拷贝只是简单地将原对象的值赋给新对象,包括指针成员的值也只是简单地复制指针的地址,这导致新对象和原对象共享同一份资源,当其中一个对象释放资源后,另一个对象仍然会引用到已释放的内存,导致错误。在拷贝中,需要自定义拷贝构造函数,以便在拷贝对象时,重新分配新的内存空间,并将原对象指针成员指向的数据复制到新的内存中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++——拷贝拷贝](https://blog.csdn.net/weixin_59179454/article/details/124935417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [C++拷贝拷贝](https://blog.csdn.net/qq_42174306/article/details/122882267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值