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

下面是用代码实现:
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 ...
随机推荐
- springmvc简单集成shiro
前言: 有天和同事聊天, 谈起权限管理, 他说他有个同事用shiro用的很溜. 正好现在有个管理平台项目, 有权限控制的需求, 因此想借此机会研究一番. 本文主要简单讲解一下对shiro的一些认识, ...
- Spring boot JPA 用自定义主键策略 生成自定义主键ID
最近学习Spring boot JPA 学习过程解决的一些问题写成随笔,大家一起成长.这次遇到自定义主键的问题 package javax.persistence; public enum Gener ...
- 关于Ctime库
--------------------- 本文来自 Fuko_Ibuki 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31908675/article/de ...
- 条件分支语句(SWICH语句)
语法 swich(条件表达式){ Case 表达式: 语句……. Break; Case 表达式: 语句……. Break; Case 表达式: 语句……. Break; default: 语句……. ...
- xshell连接linux主机时,出现错误:Could not connect to '***.***.***.***' (port 22)
xshell连接linux主机时,会出现错误:Could not connect to '192.168.89.144' (port 22): Connection failed. 但是这时能ping ...
- linux基础命令一
linux基础命令一 1.date命令 date命令介绍:显示或者设置系统日期 date命令的语法: 显示日期:date [options...] [+FORMAT] FORMAT:为显示日期的格 ...
- 在微信小程序中,如何实现下拉刷新(模拟刷新)
一.在app.json中启动刷新, 在Windows 中, 添加 "enablePullDownRefresh":"true" 二.在需要刷新的页面中写(若是 ...
- How to Install Tomcat 8.0.27 on CentOS/RHEL and Ubuntu【转】
https://tecadmin.net/install-tomcat-8-on-centos-rhel-and-ubuntu/ Apache Tomcat is an opensource web ...
- Floodlight1.2+Mininet的安装及使用
直接转载的大神的,亲测Ubuntu16.04版本没问题 https://www.sdnlab.com/19189.html
- activiti学习第二天
今天我们来发布一个流程,然后查看数据库中都发生了什么变化. 下面我们使用activiti designer设计一个流程.如图 流程很简单,我们先简单后增加难度. 创建流程图的顺序,新建一个文件夹(di ...