string类

c++中字符串的拷贝

1. c语言中,

 ·char string[] = "abcdef";//一般时候是以数组的形式进行字符串的定义

 ·strcpy(arr, array);//调用库函数进行拷贝

2. 而在c++中,利用类和对象可以进行字符串的定义与拷贝

  ·先来看一个例子,判断它的封装性

 class string

{

public:

string(const char *pstr = "")

:_pstr(new char[strlen(pstr) + 1])

{

strcpy(_pstr, pstr);

    }

//在拷贝构造函数中,s1的指针既指向s1字符串,也指向s2的指针

~string()

{

if (_pstr)

delete[]_pstr;//在主函数结束后,需要调用析构函数将s1和s2销毁掉,

//s2销毁掉之后,s1的指针就成为了野指针,会发生内存泄漏

}

private:

char *_pstr;

};

 

int main()

{

string s1("hello");

string s2(s1);//s2需要调用string类的拷贝构造函数来创建,但是没有显式定义,

//只能使用系统默认拷贝构造函数,而此时s1与s2 共用一块空间

return 0;

}

·防止内存泄漏的方法

~string()

{

if (_pstr)

delete[]_pstr;

   _pstr = NULL;//最后应该让指针指向空,才会避免内存访问违规的问题

}

·以上的拷贝为浅拷贝,编译器只是将对象中的值拷贝过来,如果对象中管理资源,最后就会导致多个对象共享一份资源,当一个对象被销毁时,将它所指向的资源释放掉,那么另一个对象不知道该资源已经被释放,所以就会发生访问违规,程序将出现崩溃。

·在浅拷贝中,由于多个对象共用同一块内存空间,所以在释放时,可能会释放多次,会引发很多问题,那么能否保证:当多个对象共用同一块空间时,该空间最终只能释放一次呢?

 有这个问题就引出了引用计数,它的原理就是当多个对象共用同一块资源时,要保证资源只能释放一次,则最简单的方法就是记录多少个对象在使用该资源,每减少(增加)一个就记录一次。当最后一个不再使用时,该对象负责将资源释放掉。

string &operator=(const string &s)

{

if (this!=s)

if (0 == --(*_pcount))//若引用计数为0,说明对象已经到最后一个,要将对象释放完,

{

delete[]_pstr;

delete[]_pcount;

}

_pstr = s._pstr;//每增加一个对象,引用计数就加1

_pcount = s._pcount;

++(*_pcount);

return *this;

}

若两个对象s1,s2共用同一块资源时,那么引用计数为2, 在使用完之后,先销毁s2,那么s2不再使用资源,pcount--;然后再销毁s1,pcount--;这样就不会引起销毁完s2之后,s1的指针成为野指针。

3. 深拷贝

·深拷贝与浅拷贝的区别就在于,浅拷贝只是拷贝了值,但是深拷贝利用拷贝构造函数进行拷贝(不是系统默认的拷贝构造函数),给每个对象独立分配资源。

·普通版

string(const char *pstr = "")

 :_pstr(new char[strlen(pstr) + 1])

 

{

strcpy(_pstr, pstr);

}

string &operator=(const string &s);

string(const string &s)

:_pstr(new char[strlen(pstr) + 1])

 

{

strcpy(_pstr, s._pstr);//最明显的区别就在于两个指针指向两块空间,不必共用一块空间

}

   ·简洁版

赋值运算符的重载,例:s3=s2

string &operator=(string &s)//相当于引用了s2,s2会自动生成一个临时变量,指向s2的指针指向的字符串

     {

         Swap(_pstr,s._pstr);//s3和s2指针的交换,实际是两个指针执行指向的内容交换了,s2指向了空,s3指向了字符串

         Return *this;//最后析构函数清理的是s2 所指向的空间。

     }

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值