六、C++语言进阶:写时拷贝技术

六、C++语言进阶:写时拷贝技术,第1张

6 写时拷贝技术
  • 定义
    在数据第一次写入到某个存储位置时,首先将原有内容拷贝出来,写到另一位置处,然后再将数据写入到存储设备中,该技术只拷贝在拷贝初始化开始之后修改过的数据。
6.1 拷贝控制
  • C++提供两个拷贝控制函数
    拷贝构造函数
    拷贝赋值运算符重载
  • 实例
class String{
public:
        String(const char* str = NULL);
        String(const String& str);
        String& operator=(const String& str);
        ~String();
        size_t size()const;
        friend ostream& operator<<(ostream& os,String const& str);
private:
        char* data;
};
6.2 深拷贝与浅拷贝
  • 概念

浅拷贝:只拷贝指针地址。
通常默认拷贝构造函数与赋值运算符重载都是浅拷贝。

深拷贝:重现分配堆内存,拷贝指针指向内容。

例如:

String::String(const char* str){
        if(NULL == str){
                data = new char[1];
                data[0] = ';'}
        else={
                data new char [strlen()str+1];strcpy
                (,data)str;}
        }
String
::~String()delete{
        [ ]; data=
        data NULL ;}
String
::String(const& String) str={
        data new char [.strsize()+1];strcpy
        (,data.str)data;}
&
String:: Stringoperator=(const& String) strif{
        (this!= & )strdelete{
                [ ]; data=
                data new char [.strsize()+1];strcpy
                (,data.str)data;}
        return
        * this;}
inline
String size_t ::size()constreturn{
        strlen ()data;}
&

ostreamoperator <<(&ostream, osconst& String) strreturn{
        << os static_cast <constvoid * (>.str)data<< ':' << . str;data}
优点
  • 比较
s_count
缺点浅拷贝
只有一份数据,节省空间。 因为多个指针指向同一个空间,容易引发同一内存多次释放的问题。深拷贝
每个指针指向不同地址,没有同一内存多次释放的问题。 存在多份相同数据,浪费空间。

浅拷贝与深拷贝的优缺点分别互为彼此的优缺点。有什么办法可以兼有二者的优点?
主要解决问题:
数据相同时只有一份内存。
不会出现多次释放问题。

6.3 计数器技术:数据相同共享一份内存

计数器技术就是兼有浅拷贝与深拷贝优点的一种技术。

在类声明中添加了计数器class

String public{
:String
        (constchar *= str NULL );String
        (const& String) str;&
        Stringoperator =(const& String) str;~
        String();size
        size_t ()const;friend
        & ostreamoperator <<(&ostream, osconstString &) str;private
:char
        *; datastatic
        int ; s_count}
;int

实现中增加计数处理

:: String=s_count 0 ;String
::String(constchar *) strif{
        (NULL== ) str={
                data new char [1];[
                data0]= ';' }else
        =new{
                data char [ strlen()+str1];strcpy(
                ,)data;str}++
        ;
        }s_countString
::
~String()if({
        --==0s_count ) delete[{
                ] ;= dataNULL
                data ; }}
        String
::
String(const&) String: strdata(.)str++data;{
        }s_count&
::
Stringoperator String=(const&) Stringif str({
        this!=& ) =str.{
                data ; str++data;
                }s_countreturn
        *
        this ;}
  • 头文件
  • class

    问题:构造新对象的计数是几?计数器技术会导致构造新对象计数错误。
    解决:每个空间应该具有自己的引用计数,而不能所有空间共享一个引用计数。

      String
    struct StringBase{
            StringBase ({
                    constchar* ); str~StringBase
                    ();char*
                    ;int data;
                    } count;
            public:
    String(
            constchar* =NULL str ) ;String(
            const&) String; str&operator
            String= (const&) String; str~String
            ();size(
            size_t )const;friend&
            operator ostream<< (&,ostreamconst os&String ); strprivate:
    *;
            StringBase} base;
    ::StringBase
    

    实现

    String::StringBase(constchar* )if str({
            NULL==) = strnew{
                    data char [ 1];[0
                    data]=';' } else=
            newchar{
                    data [ strlen ()+1str];strcpy(,
                    );data}str++;
            }
            ::countStringBase
    ::
    String~StringBase()if(--{
            ==0)count delete []{
                    ; =NULL data;
                    data } }String
            ::
    String
    
    (constchar*) =new strStringBase{
            base ( ) ;}strString::
    ~
    String()}String::{
    
    String
    (const&): Stringbase str(.)++str;base}{
            base->count&::
    operator
    String= String(const&)if String( strthis{
            !=&) -- ;str={
                    base->count.;
                    base ++ str;base}
                    base->countreturn*
            this
            ; }inlineString
    ::
    size size_t ()constreturnstrlen({
            ) ;}base->data&operator
    <<
    
    ostream( &,constostream& os)return String<< strstatic_cast{
            < os const void*( . )><<str':'base<< . ; } str&base->data::
    operator
    
    6.4 写时拷贝技术

    以上都是拷贝复制 *** 作,如果字符串发生改变,那么才是真正的写时拷贝。
    例如:实现+= *** 作

    String+= String(const&). String-- str;{
            base// 一些具体 *** 作...count=new
            StringBase
            base ( ) ;.++;
            basereturncount*this 
            ; }
  • 实例
  • # include
      #
    include# 
    includeusing 
    namespace; 
    
    class String std<
    
    char [ {
        shared_ptr];// char* s; // ptr.get()public> ptr:
        String
    (const
        char*) char* s= {
            newchar t [ strlen ()+1s];strcpy(,
            );t=sshared_ptr<
            ptr char []();>//t智能指针t}~ String
        (
        )<<__func__<< {
            cout ; } size endl(
        )
        size_t constreturnstrlen( {
            . get(ptr));}/*
            String(const String& s){}
            String& operator=(const String& s){}
            */friend
        &
        operator
        << ostream( &,constostream& os)return String<< s( {
            void os * )..gets(ptr)<<":"<< . . get s(ptr);}char&
        operator
        [] (int);operator i+(
        String const&)const Stringchar s*= {
            newchar t [ size ()+.size(s)+1];strcpy(,
            .gett(ptr));strcat(,
            ..tgets(ptr));returnString(
            ) ;}t};
        int
    main(
    ) s("Hello,World" {
        String );<<<<;
        cout = s ; endl=
    
        String t "def" s;
        t //String("def")为临时对象,用完即析构 <<<< ;
        cout << s << endl;
        cout << t + endl<<
    
        cout ; s}t [ endl5
    ]
    

    结果:

    .root@localhost /.# 0x1d59e70:a,out 
    ~0x1d59e70Hello:World
    ,String
    0x1d5a2c0:Hello0x1d5a320World
    :,def
    ~~Hello~Worlddef
    String
    String
    String
    

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/langs/1499019.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-06-25
    下一篇 2022-06-25

    发表评论

    登录后才能评论

    评论列表(0条)

    保存