//类的深拷贝和浅拷贝
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std; class Point{
public:
Point(int _a,int _b,const char *pin/*in*/){
x = _a;
y = _b;
remark = (char *)malloc(sizeof(char)*(strlen(pin) + ));
strcpy(remark, pin);
cout << "我是自定义的有参构造函数4" << endl;
}
Point(Point &pm){
cout << "我是自定义的拷贝构造函数3" << endl;
//修改拷贝构造函数
x = pm.x;
y = pm.y;
//remark = pm.remark; 这句话错误
//修改后的方案
remark = (char *)malloc(sizeof(char)*(strlen(pm.remark) + ));
strcpy(remark, pm.remark);
}
~Point(){
if (remark!=NULL)
{
free(remark);
}
cout << "我是自定义的析构函数2" << endl;
}
void GetPremark(){
printf("指针变量remark的地址是%x\n", remark);
}
//BBB---运算符重载
void operator=(Point &pm){
//CCC 解决方案第三步
if (remark!=NULL)
{
free(remark);
remark = NULL;
}
//解决方案改良第二步(以下)
x = pm.x;
y = pm.y;
remark = (char *)malloc(sizeof(char)*(strlen(pm.remark) + ));
strcpy(remark, pm.remark);
}
private:
int x;
int y;
char *remark;
}; void ProtectA(){
Point p1(, , "");
Point p2 = p1;
printf("这是p1中字符指针的地址\n");
p1.GetPremark();//打印 ad95e8
printf("这是p2中字符指针的地址\n");
p2.GetPremark();//打印 ad95e8
//这说明类对象之间拷贝指针拷贝了指针变量的值(两个指针指向同一片内存),并没有新分配内存
//出现问题:当先调用p2(函数的压栈,先定义后释放)的析构函数的时候,会释放指针变量remark指向的内存,
//当调用p1的析构函数的时候就会报错 //解决方案第一步--修改类的拷贝构造函数
//BUG事例
//Point p3;//报错 error C2512: “Point”: 没有合适的默认构造函数可用
//这说明只要定义了有参构造函数,那么c++编译器就不会自动创建无参构造函数
Point p4(,,"");
//赋值操作
//p4 = p2;
//分析:赋值操作会将p2的所有值(包括指针变量的值)拷贝到p4对象中
//此时又会出现两个指针变量指向同一片内存的情况,当析构对象p4的时候,会释放指针变量指向的内存
//那么析构p2的时候又会报错(那块内存已经被释放了,被释放了2次) //解决方案第二步--"="运算符重载
//详情见 BBB 运算符重载的使用场景
p4 = p2; //BUG事例
p4 = p1; //分析:当执行p4 = p2; p4 = p1;仔细分析"="重载函数发现,p4 = p2;p4会开辟一块内存N1,
//p4 = p1;p4会再开辟一块内存N2,此时N1这块内存永远不会被释放,这就造成了内存泄漏
//为了解决这个问题 //解决方案第三步
//我们可以在执行"="重载函数之前判断一下指针变量指向的内存又没有释放,
//(所以要确定--定义对象的时候必须要分配指针变量的内存或者将指针变量置空)
///详情见 CCC
} void main(){ ProtectA(); system("pause");
}

C++ 类的深拷贝和浅拷贝完美解决的更多相关文章

  1. C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝

    关键词:构造函数,浅拷贝,深拷贝,堆栈(stack),堆heap,赋值运算符摘要:    在面向对象程序设计中,对象间的相互拷贝和赋值是经常进行的操作.    如果对象在申明的同时马上进行的初始化操作 ...

  2. 从零开始学C++之构造函数与析构函数(三):深拷贝与浅拷贝、空类

    一.深拷贝与浅拷贝 说得简单点,假设一个类有指针成员,如果在拷贝的时候顺带连指针指向的内存也分配了,就称为深拷贝:如果只是分配指针本身的内存,那就是浅拷贝.浅拷贝造成的问题是有两个指针指向同块内存,d ...

  3. PyQt5在QWidget窗体中显示Qwidget的自定义类(补:完美解决)

    [概览] 1.显示原生Qwidget 1)不使用布局(绝对定位) 2)使用布局 2.显示Qwidget的自定义类 1)不使用布局(绝对定位)       2)使用布局 [知识点] 1.显示原生Qwid ...

  4. 探究JS中对象的深拷贝和浅拷贝

    深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj ...

  5. 理解JavaScript中的深拷贝和浅拷贝

    , num2 = num1;console.log(num1) //1console.log(num2) //1num2 = 2; //修改num2console.log(num1) //1conso ...

  6. 低门槛彻底理解JavaScript中的深拷贝和浅拷贝

    作者 | 吴胜斌 来源 | https://www.simbawu.com/article/search/9 在说深拷贝与浅拷贝前,我们先看两个简单的案例: //案例1var num1 = 1, nu ...

  7. [C#进阶系列]专题一:深入解析深拷贝和浅拷贝

    一.前言 这个星期参加了一个面试,面试中问到深浅拷贝的区别,然后我就简单了讲述了它们的之间的区别,然后面试官又继续问,如何实现一个深拷贝呢?当时只回答回答了一种方式,就是使用反射,然后面试官提示还可以 ...

  8. 【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

     c++拷贝构造函数(深拷贝,浅拷贝)详解 2013-11-05 20:30:29 分类: C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3 ...

  9. c++拷贝构造函数(深拷贝,浅拷贝)详解

    一.什么是拷贝构造函数      首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: ; int b=a;   而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.  下面 ...

随机推荐

  1. C#基础视频教程5.1 如何编写简单的超级热键

    我们上一节介绍了编写简单计算器,实际上也是出于实用角度(这个计算器只要你肯改,肯定能做的比微软自带的计算器好用).这一节介绍做简单的超级热键(所谓的超级热键是指自定义快捷键的功能) 超级热键的最关键一 ...

  2. 黑马程序员_<<TCP>>

    ---------------------ASP.Net+Android+IOS开发..Net培训.期待与您交流! -------------------- 1. TCP/IP 1.概述 要建立连接, ...

  3. XCODE修改IOS应用的名称

    原地址:http://zengwu3915.blog.163.com/blog/static/2783489720136210252843/ 首先在左侧选择你的目标组中的项目文件.在中间选择“生成”选 ...

  4. SQL Server Management Studio 简单使用说明

    1.对数据库中的数据生成脚本 a.选中要生成脚本的数据库右键->任务->生成脚本(如下图)->下一步->下一步->选中你想要生成的内容->下一步->完成

  5. VC、OpenGL、ArcGIS Engine开发的二维三维结合的GIS系统

    一.前言 众所周知,二维GIS技术发展了近四十年,伴随着计算机软硬件以及关系型数据库的飞速发展,二维GIS技术已日臻完善.在对地理信息的分析功能上有着无可比拟的优势.一些宏观的地理信息,一维的地理信息 ...

  6. findlibrary returned null产生的联想,Android ndk开发打包时我们应该怎样注意平台的兼容(x86,arm,arm-v7a)

    非常多朋友在开发Android JNI的的时候,会遇到findlibrary returned null的错误,由于某种原因,so没有打包到apk中.以下浅析下引起该错误的原因以及平台兼容性问题. A ...

  7. 【centos6.5】安装LAMP

    转载至:linux公社  https://www.linuxidc.com/Linux/2014-07/104563.htm

  8. MySQL实现允许远程用户登录(使用Navicat for MySQL工具)

    一.方式一和方式二都可以,建议方式二. 前提条件:在服务器上将MySQL的配置文件 /etc/mysql/my.cnf中使用: sudo vi /etc/mysql/my.cnf 找到bind-add ...

  9. javascript使用parseInt函数时需要注意的一些问题

    这个问题大家可能会忽视,我在项目中就遇到了.写了提醒一下大家!!! 在用javascript的parseInt函数时,parseInt("08")或者parseInt(" ...

  10. 打开office提示还有几天过期的处理办法

    是多重激活了,把激活码失效的删除即可 1.以管理员权限打开cmd(必须以管理员权限,不然无法删除无效的激活码) 2.输入命令:cd C:\Program Files (x86)\Microsoft O ...