String类的写时拷贝实例

实例如下:

#include<iostream>
using namespace std;

class String;
ostream& operator<<(ostream &out, const String&s);
//引用计数器类
class String_rep
{
  friend class String;
  friend ostream& operator<<(ostream &out, const String&s);

public:

    String_rep(const char *str )
      :use_count(0)
    {
      if (str == NULL)
      {
        data = new char[1];
        data[0] = '\0';
      }
      else
      {
        data = new char[strlen(str) + 1];
        strcpy(data, str);
      }
    }

    String_rep(const String_rep &rep) :use_count(0)
    {
      data = new char[strlen(rep.data) + 1];
      strcpy(data, rep.data);
    }
    String_rep& operator=(const String_rep &rep)
    {
      if (this != &rep)
      {
        delete[]data;
        data = new char[strlen(rep.data) + 1];
        strcpy(data, rep.data);
      }
      return *this;
    }
    ~String_rep()
    {
        delete[]data;
        data = NULL;
    }

public:

  void increase()
  {
    ++use_count;
  }

  void decrease()
  {
    if (use_count == 0)
    {
      delete this; //自杀行为  释放this所指的空间,在释放之前调动这个类的析构函数
    }
  }

private:

    char *data;
    int use_count;
};
////////////////////////////////////////////////////////////////////////////////////////
class String
{
   friend ostream& operator<<(ostream &out, const String&s);
public:
  String(const char* str = " ")
  {
    rep = new String_rep(str);
    rep->increase();
  }
  String(const String &s)
  {
    rep = s.rep;   //浅拷贝
    rep->increase();
  }
  String& operator=(const String &s)
  {
    if (this != &s)
    {
      rep->decrease();  //模拟delete
      rep = s.rep;      //模拟new
      rep->increase();   //模拟strcpy
      /*rep = s.rep;  //这会更改引用计数器指针 ,造成s内存泄漏
      rep->increase();*/
    }
    return *this;
  }
    ~String()
    {
      rep->decrease();
    }

public:

  void to_upper()
  {
    if (rep->use_count > 1)
    {
      String_rep* new_rep = new String_rep(rep->data);
      rep->decrease();
      rep = new_rep;
      rep->increase();
    }
    char* ch = rep->data;
    while (*ch != '\0')
    {
      *ch -= 32;
      ++ch;
    }
  }

private:

  String_rep *rep; //引用计数器
};

ostream& operator<<(ostream &out, const String&s)
{
  out << s.rep->data;
  return out;
}
void main()
{
  String s1("hello");
  String s2(s1);
  String s3;
  s3 = s2;
  cout << "s1=" << s1 << endl;
  cout << "s2=" << s2 << endl;
  cout << "s3=" << s3 << endl;

   s2.to_upper();

  cout << "-----------------------------------------------" << endl;

  cout << "s1=" << s1 << endl;
  cout << "s2=" << s2 << endl;
  cout << "s3=" << s3 << endl;
}

以上这篇String类的写时拷贝实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 标准C++类string的Copy-On-Write技术

    标准C++类std::string的内存共享和Copy-On-Write技术 陈皓 1.概念 Scott Meyers在<More Effective C++>中举了个例子,不知你是否还记得?在你还在上学的时候,你的父母要你不要看电视,而去复习功课,于是你把自己关在房间里,做出一副正在复习功课的样子,其实你在干着别的诸如给班上的某位女生写情书之类的事,而一旦你的父母出来在你房间要检查你是否在复习时,你才真正捡起课本看书.这就是"拖延战术",直到你非要做的时候才去做. 当然,

  • String类的写时拷贝实例

    实例如下: #include<iostream> using namespace std; class String; ostream& operator<<(ostream &out, const String&s); //引用计数器类 class String_rep { friend class String; friend ostream& operator<<(ostream &out, const String&

  • C++写时拷贝实现原理及实例解析

    一.什么是写时拷贝 写入时复制是一种计算机程序设计领域的优化策略.其核心思想是,如果有多个调用者同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变. 这个过程对其他的调用者是透明的(transparently). 此作法的主要优点是如果调用者没有修改该资源,就不会有副本被建立,因此多个调用者只是读取操作是可以共享同一

  • C++的深浅拷贝和写时拷贝你了解吗

    目录 1.浅拷贝 2.深拷贝 3.引用计数+写时拷贝 总结 1.浅拷贝 浅拷贝:对于有申请空间的对象的类来说,是按照字节序依次拷贝过去的,并没有另外申请一块空间.因此,在调用析构函数的时候会造成同一块空间释放两次的情况,从而使程序崩溃. 如下实例: class string { public: string(const char* str) { //构造string类对象时,如果传递nullptr指针 //认为程序非法,此处断言下 assert(str); _str = new char[str

  • 深入理解C/C++中的写时拷贝

    写时拷贝 何为写时拷贝? 前面我说过深拷贝浅拷贝,今天我们来探究一下写时拷贝.深拷贝是补充了浅拷贝的不足,写时拷贝其实也就是补充一点深拷贝的不足.其实写时拷贝的意思就是: 当你读取到这个空间的时候,并不会开辟出一个一模一样的空间出来给你,当你真正需要拷贝的时候,那么他就会开辟出空间给你.也就是拖延版的深拷贝. 写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(

  • c++中深浅拷贝以及写时拷贝的实现示例代码

    本文主要给大家介绍了关于c++中深浅拷贝及写时拷贝实现的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 一:浅拷贝&深拷贝 浅拷贝:在拷贝构造的时候,直接将原内容的地址交给要拷贝的类,两个类共同指向一片空间.但是存在很大的缺陷:①一旦对s2进行操作,s1的内容也会改变:②析构时先析构s2,再析构s1,但是由于s1,s2指向同一片空间,会导致一片空间的二次析构导致出错. 深拷贝:通过开辟和源空间大小相同的空间并将内容拷贝下来再进行操作.不论是否对s2进行操作,都会拷贝一片相

  • C++深浅拷贝和写时拷贝图文详解

    前言 之前我们在浅谈6个成员函数中有提到深浅拷贝的问题,现在再回首掏一把. 一.深浅拷贝哪家强? 先给出代码理一理 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include<assert.h> using namespace std; class String { friend ostream& operator<<(ostream &out, const String &s);

  • 详谈Linux写时拷贝技术(copy-on-write)必看篇

    COW技术初窥 在linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了"写时复制"技术,也就是只有进程空间的各段的内容要发生变化时,才将父进程的内容复制一份给子进程. 那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢?? 在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段.数据段.堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,其对应的物理空间是一

  • C++深浅拷贝及简易string类实现方式

    目录 三种拷贝方式 浅拷贝 深拷贝 写时拷贝 VS与GCC中的拷贝方式 Windows VS2022 Linux GCC 简易string类 传统版写法的string类 现代版写法string类 总结 三种拷贝方式 浅拷贝 对于自定义的string类,如果不显式定义拷贝构造函数,编译器会默认生成拷贝构造函数,此时的拷贝方式是浅拷贝,两个对象会公用一块儿内存,析构时同一空间被释放两次,会导致程序崩溃. 赋值运算符重载也会产生同样的问题,同时,由于被赋值对象原来有空间,浅拷贝还会导致旧的空间无法找到

  • STL 的string类怎么啦

    STL 的string类怎么啦?陈皓 前言 上个周末在和我的同学爬香山闲聊时,同学说到STL中的string类曾经让他备受折磨,几年前他开发一个系统前对string类还比较清楚,然后随着程序的复杂度的加深,到了后期,他几乎对string类失去了信心和信任,他觉得他对string类一头雾水.老实说,我几年前也有同样的痛苦(就是当我写下<标准C++类string的Copy-On-Write技术>之前的一段时间).那时,我不得不研究那根本不是给人看的SGI出品的string类的源码,代码的可读性几乎

  • Java String类的理解及字符串常量池介绍

    目录 一. String类简介 1. 介绍 2. 字符串构造 二. 字符串常量池(StringTable) 1. 思考? 2. 介绍和分析 3. intern方法 三. 面试题:String类中两种对象实例化的区别 四. 字符串的不可变性 一. String类简介 1. 介绍 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. Java的String类在lang包里,java.lang.String是java字符串类,包含

随机推荐