下面是用代码实现:

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. 深拷贝&浅拷贝&引用计数&写时拷贝

    (1).浅拷贝: class String { public: String(const char* str="") :_str(]) { strcpy(_str,str); } ...

  2. 一文搞懂Java引用拷贝、浅拷贝、深拷贝

    微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...

  3. Python 对象的引用计数和拷贝

    Python 对象的引用计数和拷贝 Python是一种面向对象的语言,包括变量.函数.类.模块等等一切皆对象. 在python中,每个对象有以下三个属性: 1.id,每个对象都有一个唯一的身份标识自己 ...

  4. Objective-C 引用计数:不讲用法,只说原理

    本文所使用的源码为 objc4-647 和 CF-1153.18 实际上这是我本周实习周报的一部分,写的比较仓促,如有差错还请多多指正. 不讲用法,只说原理. 引用计数如何存储 有些对象如果支持使用 ...

  5. python---基础知识回顾(一)(引用计数,深浅拷贝,列表推导式,lambda表达式,命名空间,函数参数逆收集,内置函数,hasattr...)

    一:列表和元组(引用计数了解,深浅拷贝了解) 序列:序列是一种数据结构,对其中的元素按顺序进行了编号(从0开始).典型的序列包括了列表,字符串,和元组 列表是可变的(可以进行修改),而元组和字符串是不 ...

  6. [iOS]深拷贝/浅拷贝区别

    来点鸡汤: // 所谓拷贝 就是在原有的对象的基础上产生一个新的副本对象.有两点原则: //   1. 改变原对象的属性和行为不会影响副本对象 //   2. 改变副本对象的属性和行为不会影响原对象 ...

  7. Objective-C 引用计数原理

    http://www.cocoachina.com/ios/20160112/14933.html 引用计数如何存储 有些对象如果支持使用 TaggedPointer,苹果会直接将其指针值作为引用计数 ...

  8. C++引用计数设计与分析(解决垃圾回收问题)

    1.引言 上一篇博文讲到https://www.cnblogs.com/zhaoyixiang/p/12116203.html 我们了解到我们在浅拷贝时对带指针的对象进行拷贝会出现内存泄漏,那C++是 ...

  9. OC基础15:内存管理和自动引用计数

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...

随机推荐

  1. 【leetcode】414. Third Maximum Number

    problem 414. Third Maximum Number solution 思路:用三个变量first, second, third来分别保存第一大.第二大和第三大的数,然后遍历数组. cl ...

  2. 【转】Spring-boot 字符集设置 解决乱码方案

    使用spring-boot开发时候,有时候程序没事,往往不经意会造成中文到前端变成乱码(????这样情况) 下面给出spring-boot项目统一字符集设置方案: 1.Spring Boot修改编码方 ...

  3. idea xml版本修改问题

    STEP 1.选中模块 STEP 2.file---->Project Structure---->Facets---->把相应模块的给删除"-"----> ...

  4. 小妖精的完美游戏教室——人工智能,A*算法,引言

    今天也要直播魔法,求科学的! 欢迎来到小妖精Balous的完美游戏教室! 经过前两周的学习,相信米娜桑已经对状态机有所了解了呢~虽然状态机能够实现几乎所有的人工智能,但是,在实践中,你们有没有发现,自 ...

  5. CodeForces - 13E

    Little Petya likes to play a lot. Most of all he likes to play a game «Holes». This is a game for on ...

  6. saltstack基础知识

    saltstack简介 saltstack基于python开发的C/S架构的配置管理工具,分为服务器端salt-master和客户端salt-minion.并且支持浩称最快的ZeroMQ消息队列机制, ...

  7. Java12配置

    配置环境变量: 之前的JAVA_HOME和CLASSPATH已经都不要了.只要配置jdk的bin到Path里: C:\Program Files\Java\jdk-12\bin

  8. <Differential Geometry of Curves and Surfaces>(by Manfredo P. do Carmo) Notes

    <Differential Geometry of Curves and Surfaces> by Manfredo P. do Carmo real line Rinterval I== ...

  9. CSS之metra&title&base&target

    <!DOCTYPE html><html lang="en"><head> <style type="text/css" ...

  10. activity--生命周期总结

    22.Android禁止屏幕旋转 & 旋转屏幕时保持Act内容? 21.旋转屏幕Act执行的生命周期方法? 12.ActA与 ActB互相跳转生命周期情况? 11.Act的生命周期? ==== ...