C++の深浅コピー及びString類基本操作

5810 ワード

今日はC++での深浅コピーについてご紹介します.
一.浅いコピー
1.定義:ビットコピーとも呼ばれ、コンパイラはオブジェクトの値を基本タイプの値でコピーするだけで、オブジェクトでリソースを管理すると、最後に複数のオブジェクトが同じリソースを共有し、1つのオブジェクトが破棄されるとそのリソースが解放されますが、他のオブジェクトはそのリソースが解放されたことを知りません.まだ有効だと思っています.したがって、リソースの操作を続行すると、アクセス違反の問題が発生します.
2.例:
class String
{
public:
	String(const char* str="")                     //    
		:_pstr(new char[strlen(str)+1])        //     
	{
		strcpy(_pstr,str);                     //  
		cout<

これが浅いコピーです.クラスのメンバー変数がポインタの場合、コピー構造関数を自分で書かないため、システムは自動的に生成されます.この場合、システムはコンテンツをコピーするだけなので、2つのオブジェクトが同じリソースを同じアドレスに占有し、解放時にメモリアクセス違反が複数回発生します.したがって、浅いコピーはクラス内の単純なデータ・メンバーに値を割り当てるだけで、クラスのメンバー変数にポインタ・メンバーが存在する場合、問題が発生し、ポインタのみをコピーし、アドレスを変更しません.これが浅いコピーです.
二.深いコピー:
1.メンバーがポインタである場合、深いコピーはポインタだけでなく、ポインタが指す内容をコピーし、深いコピー後のポインタは2つの異なるアドレスを指すポインタであり、問題が発生しない.
2.例:(1)従来法の深いコピー:
class String
{
public:
	String(const char* str="")         //    
	{
		if(str==NULL)              //        。
		{
			str="";
		}
		_pstr=new char[strlen(str)+1];  //      。
		strcpy(_pstr,str);
		cout<

(2)簡潔版の深いコピー:
class String
{
public:
	String(const char* str="")
	{
		if(str==NULL)
		{
			str="";
		}
		_pstr=new char[strlen(_pstr)+1];
		strcpy(_pstr,str);
	}

	~String()
	{
		if(_pstr)
		{
			delete[] _pstr;
			_pstr==NULL;
		}
	}

	String(const String& s)
		:_pstr(NULL)
	{
		String t(s._pstr);
		swap(_pstr,s._pstr);
	}

	String& operator=(const String& s)
	{
		String t(s);
		swap(s._pstr,t._pstr);
		return *this;
	}

private:
	char* _pstr;
};
int main()
{
	String s1("hello");
	String s2(s1);
	
	return 0;

}

深いコピーでは、コピー構造関数を定義しているので、デフォルトの関数は使用されません.この場合、新しいアドレス空間が開きます.したがって、2つのオブジェクトが指すアドレスが異なると、メモリアクセス違反は発生しません.
3.したがって、総じて、クラスにポインタメンバー変数がある場合は、できるだけ自分でコピー構造関数を書くようにして、浅いコピーの問題を引き起こすことはありません.
三.Stringクラスの追加削除:
//String      :
class String
{
public:
	String(const char* str="")            //    
	{
		_size=_capacity=strlen(str);
		_str=new char[strlen(str)+1];
		_capacity=_size;
		strcpy(_str,str);
	}
	~String()                            //    
	{
		if(_str)
		{
			delete[] _str;
			_size=_capacity=0;
			_str=NULL;
		}
	}
	void Swap(String& s)                  //  
	{
		swap(_str,s._str);
		swap(_size,s._size);
		swap(_capacity,s._capacity);
	}
	String(const String& s)               //      
		:_str(NULL)
		,_size(0)
		,_capacity(0)
	{
		String t(s._str);
		Swap(t);
	}

	String& operator=(String s)           //       
	{
		Swap(s);
		return *this;
	}
	void expand(size_t n)                  //    
	{
		if(n>_capacity)
		{
			char* t=new char[n+1];
			strcpy(t,_str);
			delete[] _str;
			_str=t;
			_capacity=n;
		}
	}
	void PushBack(char ch)                //    
	{
		if(_size==_capacity)
		{
			expand(_capacity*2);
		}
		_str[_size]=ch;
		_size++;
		_str[_size]='\0';
	}
	void PushBack(const char* s)          //     
	{
		size_t len=strlen(s);
		if(len>_capacity)
		{
			expand(_capacity*2);
		}
		strcpy(_str+_size,s);
		_size=_size+len;
	}

	void PopBack()                      //  
	{
		if(_size==0)
		{
			return;
		}
		_size--;
		_str[_size]='\0';
	}
	void PushFront(char ch)             //    
	{
		int i=0;
		if(_size==_capacity)
		{
			expand(2*_capacity);
		}
		for(i=_size;i>=0;i--)
		{
			_str[i+1]=_str[i];
		}
		_str[0]=ch;
		_size++;
	}

	void PushFront(const char* s)           //     
	{
		char *p=_str;
		size_t len=strlen(s);
		int i=0;
		if(_size+len>=_capacity)
		{
			expand(2*_capacity);
		}
		for(i=_size;i>=0;i--)
		{
			_str[i+len]=_str[i];
		}
		while(*s)
		{
			*p++=*s++;
		}
		_size+=len;
	}

	void PopFront()                      //  
	{
		int i=0;
		if(_size==0)
		{
			return;
		}
		if(_size==1)
		{
			_size--;
			return;
		}
		for(i=0;i<_size _str="" _size--="" void="" insert="" pos="" char="" ch="" int="" i="0;" if="" expand="" for="">(int)pos;i--)
		{
			_str[i+1]=_str[i];
		}
		_str[pos+1]=ch;
		_size++;
	}
	void Insert(size_t pos,const char* s)          //         
	{
		int i=0;
		size_t len=strlen(s);
		if(_size+len>_capacity)
		{
			expand(2*_capacity);
		}
		for(i=_size;i>pos;i--)
		{
			_str[i+len]=_str[i];
		}
		while(*s)
		{
			_str[++pos]=*s++;
		}
		_size+=len;
	}

	void Erase(size_t pos, size_t n = 1)         //        n  
	{
		if(pos+n>_size-1)
		{
			_str[pos]='\0';
			_size=pos;
		}
		else{
			strcpy(_str+pos,_str+pos+n);
			_size-=n;
		}
	}

	size_t Find(char ch)                      //      
	{
		size_t i=0;
		for(i=0;i<_size if="" return="" i="" void="" replace="" ch1="" char="" ch2="" int="" for="" _str="" bool="" operator="" string="" s="" const="" a="_size;" b="s._size;" j="">s._str[j])
			{
				return 0;
			}
		}
		if(i==a && j(const String& str) const        //     
	{
		return (!(*this=(const String& str) const        //      
	{
		return ((*this>str)&&(*this==str));
	}

	bool operator<=(const String& str) const       //      
	{
		return !(*this>str);
	}

	char& operator[](size_t pos)                  //[]   。
	{
		if(pos>_size)
		{
			return _str[_size];
		}
		return _str[pos];
	}

	const char * c_str()                    
	{
		return _str;
	}

	const size_t Size()
	{
		return _size;
	}
private:
	char *_str;
	size_t _size;
	size_t _capacity;
};