从String类中看C++当中的深拷贝与浅拷贝解

    了解过C++语言的人,都应该知道,C++语言中的构造函数,析构函数,拷贝构造函数,赋值运算符重载函数,如果不定义,编译器会自动生成的,当然,生成的只是一些最基本的,在达不到我们要求的条件下,就需要我们自己重新定义这些函数。

创新互联专注为客户提供全方位的互联网综合服务,包含不限于成都网站设计、成都网站建设、丰林网络推广、微信小程序定制开发、丰林网络营销、丰林企业策划、丰林品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供丰林建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com

    我们现在说的讲的是深拷贝与浅拷贝,当然讨论这个问题的基础,一般情况下是我们定义的变量是以指针形式出现的,原因就在于,不论赋值还是拷贝,我们要实现两个指针指向的内容一致,那我得到新的指针和原指针是指向同一块内存空间还是两块内存空间的相同内容。如果是指向同一块空间,就存在了安全隐患,我们在自己管理空间时,就很有可能对一块空间进行了多次的释放,有些编译器下会报错,甚至直接奔溃,有些编译器虽不会抛出异常,但也会对后续的程序造成未知的错误。

 

那么,现在就以String为例,看看如何解决这些问题。

 

//参数列表中,pstr为char* 类型,s为String类型

//实现方法1:

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* pstr) :_str(new char[strlen(pstr)+1])
 {
  strcpy(_str,pstr);
  cout << "构造" << endl;//做标识
 }
 String(const String& s) :_str(new char[strlen(s._str) + 1])
 {
  strcpy(_str,s._str);
  cout << "拷贝构造"<

 

//*****************************************************************************************

 

//String类的实现2

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* str) :_str(new char[strlen(str)+1])//同上
 {
  strcpy(_str,str);
 }
 //拷贝构造
 String(const String& s) : _str(NULL)
 {
  String tmp(s._str);
  std::swap(_str,tmp._str);
 }
 //赋值运算符重载
 //String&operator=(const String& s)
 //{
 // if (this != &s)
 // {
 //  char* tmp(s._str);//用s._str或者s实例化tmp都可以
 //  std::swap(_str,tmp);
 // }
 // return *this;
 //}
 
 //赋值运算符重载之开辟空间法
 String&operator=(const String& s)
 {
  if (this != &s)
  {
   char* tmp = new char[strlen(s._str) + 1];
   strcpy(tmp,s._str);
   delete[]_str;
   _str = tmp;
  }
  return *this;
 }
 //析构
 ~String()
 {
  if (NULL == _str)
  {
   delete[] _str;
   _str = NULL;
  }
 }
private:
 char* _str;
};
//输出运算符重载
ostream& operator<<(ostream& _out,const String& s)
{
 _out << s._str<< endl;
 return _out;
}

 

// String类的实现3------>浅拷贝实现防止内存的多次释放

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* pdata)
  :_str(new char[strlen(pdata)+1])
  , _count(new int)
 {
  strcpy(_str,pdata);
  *_count = 1;
 }
 String(const String& s)
  :_str(s._str)
  , _count(s._count)
 {
  _count++;
 }
 
 String& operator=(const String& s)
 {
  if (this != &s)
  {
   if (--(*_count) == 0)
   {
    delete[]_str;
    delete _count;
   }
   _count = s._count;
   _str = s._str;
   _count++;
  }
  return* this;
 }
 ~String()
 {
  if (--(*_count) == 0)
  {
   delete[] _str;
   delete _count;
  }
 }
private:
 char* _str;
 int* _count;
};
//输出运算符重载
ostream& operator<<(ostream& _out,const String& s)
{
 _out << s._str<< endl;
 return _out;
}

//*****************************************************************************************

友元函数受第一参数的限制,只能采用类外定义,引入友元

方法三,关于引入计数器,在面试过程中,这是最不推荐的方法,HR往往更倾向于让你写出深拷贝的方法。

 

深拷贝与浅拷贝是面试过程中经常出现的题目,弄清楚这类问题是非常必要的

 

 

 

 


网页标题:从String类中看C++当中的深拷贝与浅拷贝解
当前URL:http://myzitong.com/article/ihochi.html