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

下面是用代码实现:
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 ...
随机推荐
- Spring mvc 加载HTML静态页面
看到网上大部分举例Spring MVC加载静态页面HTML方式都还要通过controller, 根据js和css文件的加载模式,html也同样可以直接加载 在spring的配置文件中例如 *-serv ...
- Codeforces 1080C- Masha and two friends
AC代码 #include <bits/stdc++.h> #define ll long long const int maxn=1e6+10; using namespace std; ...
- zombodb 索引管理
zombodb 支持标准的index 管理(create .alter.drop) 创建索引 CREATE INDEX index_name ON table_name USING zombodb ( ...
- RabbitMQ 死信队列 延时
package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ...
- Zuul 跨域
JS访问会出现跨域问题的解决, 一.对单个接口,处理跨域,只需要在被调用的类或或方法增加注解 CoossOrigin 如下设置 allowCredenticals=true,表示运行Cookie跨域 ...
- ID的故事
随心所欲.这个时代比较中二吧,刚出国,也买了房,年纪轻轻的觉得自己好像很牛B的样子. 失败悲观的路人甲.大约是13年的时候,突遭重击,一下子悲观失望,死的心都有.为此买了那种自杀也会给赔偿的保险(买后 ...
- UEFI和GPT下硬盘克隆后的BCD引导修复
UEFI和GPT下硬盘克隆后的BCD引导修复-Storm_Center http://www.stormcn.cn/post/1901.html 当硬盘引导换成GPT,系统启动也变成UEFI后,如果直 ...
- TCP/IP学习20180630-数据链路层-router choose
IP路由选择 当一个IP数据包准备好了的时候,IP数据包(或者说是路由器)是如何将数据包送到目的地的呢?它是怎么选择一个合适的路径来"送货"的呢? 最特殊的情况是目的主机和主机直连 ...
- VS在.NETFramework升级时遇到类库冲突如何解决
相信大家在开发环境中随着程序的不断升级,很多时间需要升级. NETFramework版本.今天项目中遇到的问题是从. NETFramework4.0升级到4.5时提示 Entityframework. ...
- 如何让Excel单元格中的名字分散对齐
1 操作方式 开始->对齐方式->对齐->水平对齐->分散对齐(缩进) 2 优势 不会破坏数据的有效性