引用计数——深拷贝&浅拷贝

下面是用代码实现:
private:
char *data;
size_t use_count;
public:
//构造函数
String_rep(const char *str = ""):use_count()
{
if(str == NULL)
{
data = new char[];
data[] = '\0';
}
else
{
data = new char[strlen(str)+];
strcpy(data,str);
}
}
//拷贝构造函数
String_rep(const String_rep &rep);
//析构函数
~String_rep()
{
if(use_count == )
{
delete[] data;
data = NULL;
}
}
private:
String_rep *rep;
public:
String(const char *str = ""):rep(new String_rep(str))
{
rep->increment();
}
String(const String &s)
{
rep = s.rep;
rep->increment();
}
~String()
{
rep->decrement();
}
注意理解下面这一段:(调试记录图)
//析构函数
~String_rep()
{
if(use_count == )
{
delete[] data;
data = NULL;
}
}

还要注意一点,如果要修改其中的内容的话就得先开一块空间,把值拷贝过来然后,再在里面进行修改。
eg:
void upper()
{
rep->decrement();
rep = new String_rep(rep->data); int n = strlen(rep->data);
for(int i=;i<n;++i)
{
if(rep->data[i] >='a'&&rep->data[i]<='z')
rep->data[i] = rep->data[i] - ;
}
rep->increment(); }
以String类的实现来做个示例:
#pragma once
#include<iostream>
using namespace std; class String;
ostream& operator<<(ostream &out, const String &s);
void Turn(String &s); class String_rep
{
friend void Turn(String &s);
friend class String;
friend ostream& operator<<(ostream &out, const String &s);
private:
char *data;
size_t use_count;
public:
//构造函数
String_rep(const char *str = ""):use_count()
{
if(str == NULL)
{
data = new char[];
data[] = '\0';
}
else
{
data = new char[strlen(str)+];
strcpy(data,str);
}
}
//拷贝构造函数
String_rep(const String_rep &rep);
//析构函数
~String_rep()
{
if(use_count == )
{
delete[] data;
data = NULL;
}
}
public:
void increment()
{
++use_count;
}
void decrement()
{
--use_count;
}
};
class String
{
friend void Turn(String &s);
friend ostream& operator<<(ostream &out, const String &s);
private:
String_rep *rep;
public:
String(const char *str = ""):rep(new String_rep(str))
{
rep->increment();
}
String(const String &s)
{
rep = s.rep;
rep->increment();
}
~String()
{
rep->decrement();
}
String &operator = (const String &s)
{
if(this !=&s)
{
rep->decrement();
rep = s.rep;
rep->increment();
}
return *this;
}
String &operator+(const String &s1)
{
char *tempch;
int n = strlen(rep->data)+strlen(s1.rep->data)+;
tempch = new char[n];
strcpy(tempch,rep->data);
strcat(tempch,s1.rep->data);
String *temp;
temp = new String(tempch);
temp->rep->decrement();
return *temp;
}
String &operator+=(const String &s1)
{
char *tempch;
int n = strlen(rep->data)+strlen(s1.rep->data)+;
tempch = new char[n];
strcpy(tempch,rep->data);
strcat(tempch,s1.rep->data); String_rep *temp;
temp = new String_rep(tempch);
int remsize = rep->use_count;
rep = temp;
rep->use_count = remsize;
delete tempch;
return *this;
}
void upper()
{
rep->decrement();
rep = new String_rep(rep->data); int n = strlen(rep->data);
for(int i=;i<n;++i)
{
if(rep->data[i] >='a'&&rep->data[i]<='z')
rep->data[i] = rep->data[i] - ;
}
rep->increment(); }
};
ostream& operator<<(ostream &out, const String &s)
{
out<<s.rep->data;
return out;
}
使用轮子:
#include"use_count_string.h"
int main()
{
String st1("asdfghj");
String st2(st1);
String st6(st1);
String st7(st1);
String st3("qwerty");
String st5("Anna");
String st4;
st4 = st1 + st3;
st5 += st3;
st1 = st3;
cout<<"st1 = "<<st1<<endl;
cout<<"st2 = "<<st2<<endl;
cout<<"st3 = "<<st3<<endl;
cout<<"st4 = "<<st4<<endl;
cout<<"st5 = "<<st5<<endl;
st2.upper();
cout<<"st2 = "<<st2<<endl;
return ;
}
引用计数——深拷贝&浅拷贝的更多相关文章
- 深拷贝&浅拷贝&引用计数&写时拷贝
(1).浅拷贝: class String { public: String(const char* str="") :_str(]) { strcpy(_str,str); } ...
- 一文搞懂Java引用拷贝、浅拷贝、深拷贝
微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...
- Python 对象的引用计数和拷贝
Python 对象的引用计数和拷贝 Python是一种面向对象的语言,包括变量.函数.类.模块等等一切皆对象. 在python中,每个对象有以下三个属性: 1.id,每个对象都有一个唯一的身份标识自己 ...
- Objective-C 引用计数:不讲用法,只说原理
本文所使用的源码为 objc4-647 和 CF-1153.18 实际上这是我本周实习周报的一部分,写的比较仓促,如有差错还请多多指正. 不讲用法,只说原理. 引用计数如何存储 有些对象如果支持使用 ...
- python---基础知识回顾(一)(引用计数,深浅拷贝,列表推导式,lambda表达式,命名空间,函数参数逆收集,内置函数,hasattr...)
一:列表和元组(引用计数了解,深浅拷贝了解) 序列:序列是一种数据结构,对其中的元素按顺序进行了编号(从0开始).典型的序列包括了列表,字符串,和元组 列表是可变的(可以进行修改),而元组和字符串是不 ...
- [iOS]深拷贝/浅拷贝区别
来点鸡汤: // 所谓拷贝 就是在原有的对象的基础上产生一个新的副本对象.有两点原则: // 1. 改变原对象的属性和行为不会影响副本对象 // 2. 改变副本对象的属性和行为不会影响原对象 ...
- Objective-C 引用计数原理
http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer,苹果会直接将其指针值作为引用计数 ...
- C++引用计数设计与分析(解决垃圾回收问题)
1.引言 上一篇博文讲到https://www.cnblogs.com/zhaoyixiang/p/12116203.html 我们了解到我们在浅拷贝时对带指针的对象进行拷贝会出现内存泄漏,那C++是 ...
- OC基础15:内存管理和自动引用计数
"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...
随机推荐
- openssl查看apk的证书信息
查看apk的证书信息: openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
- char * p = "abc"与const char *p = "abc"
char * p = "abc"与const char *p = "abc"的区别是什么呢? 第一个语句会产生问题: warning: deprecated c ...
- 《从Lucene到Elasticsearch:全文检索实战》学习笔记四
今天我给大家讲讲布尔检索模型基本概念 布尔检索模型: 检索模型是判断文档内容与用户相关性的核心技术,以大规模网页搜索为例,在海量网页中与用户查询关键词相关的网页可能会有成千上万个,甚至耕读哦.那么信息 ...
- linux局域网内挂载其它操作系统目录
一.linux挂载windows 1.windows目录打开共享: 2.mount -t cifs -o username=admin***tor,password=abc //192.168.*** ...
- 使用rpm 打包开发的postgres extension
环境准备 安装依赖包 rpmdevtools rpm-build yum install -y rpm-build rpmdevtools 初始化rpm pacakge 项目 主要是rpm 打包的 ...
- Centos7更改yum源
每次都要百度一番,还不如自己做个记录,简单粗暴,哈哈哈哈 cd /etc/yum.repos.d mv CentOS-Base.repo CentOS-Base.repo.old wget http: ...
- Entity Framework Code first 可能会导致循环或多个级联路径.
用code first映射数据库报错 Introducing FOREIGN KEY constraint 'FK_dbo.Roles_dbo.SubSystems_SubSystemID' on t ...
- Github访问速度慢和下载慢的解决方法
原因 为什么访问速度慢.下载慢?github的CDN被某墙屏了,由于网络代理商的原因,所以访问下载很慢.Ping github.com 时,速度只有300多ms. 解决方法 绕过dns解析,在本地直接 ...
- java中拼接两个对象集合
目标: 根据两个list中每条记录的某个属性是否相同来拼接. 1.首先定义一个字符串 String str = "[{\"ITEMID\":2,\"ITEMN ...
- Linux系统重置root用户密码
Linux系统重置root用户密码 作者:Eric 微信:loveoracle11g 查看系统版本是不是RHEL7 [root@zhouwanchun ~]# cat /etc/redhat-rele ...