C++中的浅拷贝是产生很多问题的根本原因,其根本原因是在有指针的时候,只是拷贝了一个指针的值,多个指针指向同一块内存区域,当free内存时,造成其他指针指向的空间不存在。结合构造函数和析构函数理解浅拷贝是一个不错的选择

原始程序

#include "iostream"
using namespace std; class Name
{
public:
Name(const char *pname)
{
size = strlen(pname);
pName = (char *)malloc(size + 1);
strcpy(pName, pname);
}
~Name()
{
cout<<"开始析构"<<endl;
if (pName!=NULL)
{
free(pName);
pName = NULL;
size = 0;
}
} protected:
private:
char *pName;
int size;
}; void playObj()
{
Name obj1("obj1.....");
}
void main()
{
playObj();
system("pause");
}

对象的初始化

使用对象的初始化时候,会调用copy构造函数,在copy构造函数中进行深拷贝

#include "iostream"
using namespace std; class Name
{
public:
Name(const char *pname)
{
size = strlen(pname);
pName = (char *)malloc(size + 1);
strcpy(pName, pname);
}
Name(Name &obj)
{
//用obj来初始化自己
pName = (char *)malloc(obj.size + 1);
strcpy(pName, obj.pName);
size = obj.size;
}
~Name()
{
cout<<"开始析构"<<endl;
if (pName!=NULL)
{
free(pName);
pName = NULL;
size = 0;
}
} protected:
private:
char *pName;
int size;
}; void playObj()
{
Name obj1("obj1.....");
Name obj2 = obj1; //obj2创建并初始化
}
void main()
{
playObj();
system("pause");
}

对象的=操作

在对象的=操作的时候,也是浅拷贝,此时需要使用运算符重载来解决问题

#include "iostream"
using namespace std; class Name
{
public:
Name(const char *pname)
{
size = strlen(pname);
pName = (char *)malloc(size + 1);
strcpy(pName, pname);
}
Name(Name &obj)
{
//用obj来初始化自己
pName = (char *)malloc(obj.size + 1);
strcpy(pName, obj.pName);
size = obj.size;
}
~Name()
{
cout<<"开始析构"<<endl;
if (pName!=NULL)
{
free(pName);
pName = NULL;
size = 0;
}
}
void operator=(Name &obj3)
{
//用obj3来=自己
pName = (char *)malloc(obj3.size + 1);
strcpy(pName, obj3.pName);
size = obj3.size;
} protected:
private:
char *pName;
int size;
}; void playObj()
{
Name obj1("obj1.....");
Name obj2 = obj1; //obj2创建并初始化
Name obj3("obj3...");
obj2 = obj3;
}
void main()
{
playObj();
system("pause");
}

上面程序存在的问题

在以上程序中,存在内存泄漏,obj2的指针重新指向的时候,原来的内存没有释放

#include "iostream"
using namespace std; class Name
{
public:
Name(const char *pname)
{
size = strlen(pname);
pName = (char *)malloc(size + 1);
strcpy(pName, pname);
}
Name(Name &obj)
{
//用obj来初始化自己
pName = (char *)malloc(obj.size + 1);
strcpy(pName, obj.pName);
size = obj.size;
}
~Name()
{
cout<<"开始析构"<<endl;
if (pName!=NULL)
{
free(pName);
pName = NULL;
size = 0;
}
}
void operator=(Name &obj3)
{
if (pName != NULL)
{
free(pName);
pName = NULL;
size = 0;
}
//用obj3来=自己
pName = (char *)malloc(obj3.size + 1);
strcpy(pName, obj3.pName);
size = obj3.size;
} protected:
private:
char *pName;
int size;
}; void playObj()
{
Name obj1("obj1.....");
Name obj2 = obj1; //obj2创建并初始化
Name obj3("obj3...");
obj2 = obj3;
}
void main()
{
playObj();
system("pause");
}

C++之用程序理解浅拷贝的更多相关文章

  1. python之浅拷贝和深拷贝

    1.浅拷贝 1>赋值:从下面的例子我们可以看到赋值之后新变量的内存地址并没有发生任何变化,实际上python中的赋值操作不会开辟新的内存空间,它只是复制了新对象的引用,也就是说除了b这个名字以外 ...

  2. python的拷贝(深拷贝和浅拷贝)

    今天看了几篇关于python拷贝的博文,感觉不太清楚,所以我就自己做实验试一下,特此记录. 拷贝是针对组合对象说的,比如列表,类等,而数字,字符串这样的变量是没有拷贝这一说的. 实现拷贝有: 1.工厂 ...

  3. C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝

    原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...

  4. iOS 浅谈:深.浅拷贝与copy.strong

    深.浅拷贝 copy mutableCopy NSString NSString *string = @"汉斯哈哈哈"; // 没有产生新对象 NSString *copyStri ...

  5. Objective-C中的浅拷贝和深拷贝(转载)

    本文转自:http://segmentfault.com/blog/channe/1190000000604331 浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.如: ...

  6. C++ 系列:深拷贝与浅拷贝

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  7. [转] js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = ...

  8. Objective-C中的深拷贝和浅拷贝

    在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...

  9. $.extend()的深拷贝和浅拷贝详细讲解

    版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...

随机推荐

  1. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  2. 【leetcode】1283. Find the Smallest Divisor Given a Threshold

    题目如下: Given an array of integers nums and an integer threshold, we will choose a positive integer di ...

  3. [Python]token的生成及验证

    hmac模块(仅在python3中可以使用) 简介: HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出. 典型应用: HMAC的一 ...

  4. springboot读取配置信息、环境变量

    2.读取配置文件 2.1 读取核心配置文件 核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法 ...

  5. 1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组

    1012 最大公约数和最小公倍数问题 2001年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 输入二个 ...

  6. 服务不支持 chkconfig 的解决办法

    在chkconfig --add servername的时候老是提示服务不支持 chkconfig 经过查找,解决办法如下. 1.脚本tomcatstart前三行如下: #!/bin/bash #ch ...

  7. C++入门经典-例8.2-构造函数的访问顺序

    1:父类和子类中都有构造函数和析构函数,那么子类对象在创建时是父类先进行构造还是子类先进行构造?同样,在子类对象释放时,是父类先进行释放,还是子类先进行释放?这都是有先后顺序的.答案是当从父类派生一个 ...

  8. Web存储机制—sessionStorage,localStorage使用方法

    Web存储机制,在这里主要聊有关于Web Storage API提供的存储机制,通过该机制,浏览器可以安全地存储键值对,比使用cookie更加直观.接下来简单的了解如何使用这方面的技术. 基本概念 W ...

  9. 解决Git 报错:warning: LF will be replaced by CRLF

    Ruby命令 $ git init $ git add . 系统出现如下错误:warning: LF will be replaced by CRLF 原因分析:CRLF -- Carriage-Re ...

  10. vue-cli构建的项目结构解析

    参考: https://www.jianshu.com/p/32beaca25c0d