C ++文字列クラスの問題の詳細なコピー深さ

文字列クラスオブジェクトの操作能力

関数名 機能
サイズ 有効な文字の文字列の長さを返します。
長さ 有効な文字の文字列の長さを返します。
容量 スペースの合計サイズを返します。
空の 文字列の解放を検出することは、空の文字列は真、そうでない場合はfalseが返されています
晴れ 空の効果的なキャラクター
予備 文字列のためのスペースを確保
リサイズ Nへの有効な文字の数、余分なスペースは、文字cで満たされています

ご注意ください

  1. 一般的に、基本的にはサイズが、他のコンテナと一致するように正確にインターフェースの同じ基本原理を、組み込まれたサイズ()を達成するために長さ()メソッドとサイズ()を引き起こします()。
  2. クリア()基本となるスペースを変更せずに、空になった文字列の唯一の有効な文字です。
  3. リサイズ(n)は、余分なゼロが埋め込ま:文字の数の増加をサイズ変更するときは(size_t n)とリサイズ(size_tのN、チャーC)nに変更された文字列内の文字の有効数は、異なっています文字cと素子間隔、サイズ変更(size_tのN、チャーc)は、余分なスペース要素を充填します。注:要素の数を変更する際の要素の数が増加した場合、それは要素数、基礎となる空間不変量の合計サイズを低減することである場合、容量は、底部の大きさを変更することができるリサイズ。
  4. リザーブ(size_tのres_arg = 0):予備少ないストリングの底部の合計サイズのパラメータ空間より大きい場合、文字列のための予約領域は、素子の有効数を変えずに、リザーバの容量がサイズを変更しません。<15 newCapacityない限り。変更は、スペースの有効サイズや要素数よりも小さい場合や、サイズを変更しません。

文字列クラスのアナログ実装

class String 
{ 
public:    
	String(const char* str = "")    
	{ 
		if(nullptr == str)
 		{
			assert(false);
			return;
 		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}        
	~String()   
	{ 
		if(_str)
 		{
			delete[] _str;
			_str = nullptr;
 		}
	}   
private:    
	char* _str; 
};
 
void TestString() 
{    
	String s1("hello bit!!!");    
	String s2(s1); 
} 

注ことを Stringクラス以上明示的にコピーコンストラクタと代入演算子のオーバーロードを定義しない、S1、S2で構成され、この時コンパイラ合成し、デフォルトでは、コンパイラはデフォルトのコピーコンストラクタを呼び出します。最後の問題が原因で、S1、S2、リリーススペースで複数回は、クラッシュにこのコピーモードをプログラムを原因とするためにリリースされたときに、同じメモリ空間を共有し、浅いコピーと呼ばれます。

ディープコピー

コンストラクタ、代入演算およびデストラクタオーバーロードをコピーするリソース管理に関連するクラスは、明示的に表現されなければならない場合。これは、一般的な深いコピーモードに従って提供されます。

Stringクラスの伝統的な書き込み

class String 
{ 
public:    
	String(const char* str = "")    
	{        
		if(nullptr == str)        
		{            
			assert(false);            
			return;        
		}                
		_str = new char[strlen(str) + 1];        
		strcpy(_str, str)}        
	String(const String& s)        
		: _str(new char[strlen(s._str)+1])    
	{            
		strcpy(_str, s._str);    
	}        
	String& operator=(const String& s)    
	{ 
		 if(this != &s)        
		 {            
		 	char* pStr = new char[strlen(s._str) + 1];            
		 	strcpy(pStr, s._str);            
		 	delete[] _str;            
		 	_str = pStr; 
		 }
		 return *this;
	}
	~String()    
	{
		 if(_str)        
		 {            
		 	delete[] _str;            
		 	_str = nullptr;        
		 } 
	}
private:    
	char* _str; 
};

Stringクラスの近代的な言葉遣い

class String 
{ 
public:    
	String(const char* str = "")    
	{
		 if(nullptr == str)            
		 	str = "";                
		 _str = new char[strlen(str) + 1];        
		 strcpy(_str, str)}        
	 String(const String& s)        
	 	: _str(nullptr)    
	 {        
	 	String strTmp(s._str);        
	 	swap(_str, strTmp);    
	 }    
	String& operator=(String s)    
	{        
		swap(_str, s._str);           
		return *this;    
	}        
	/*    
	String& operator=(const String& s)    
	{        
		if(this != &s)
        {
        	String strTmp(s);           
        	swap(_str, strTmp._str);        
        }                
        return *this;    
    }    
    */        
    ~String()    
    {        
    	if(_str)        
    	{            
    		delete[] _str;            
    		_str = nullptr;        
    	}    
    }    
private:    
	char* _str; 
};

コピーを書くとき

  • 先延ばしは、コピー・オン・ライトの一種で、達成するために増加した参照カウントのシャローコピーに基づいています。
  • 参照カウント:リソースの利用者数を記録するために使用されます。設定されている場合、1にカウントするリソースは、リソースカウントを使用して、各追加の目的は、1だけインクリメントされ、得られたオブジェクトが破棄される場合、1カウントを与え、リソースの解放かどうかをチェックし、その後、もしターゲット・リソースの最後のユーザを示す、1のカウントが、リソースが解放され、リソースの使用の他のオブジェクトがあるので、それ以外の場合は解放することはできません。
公開された157元の記事 ウォン称賛53 ビュー50000 +

おすすめ

転載: blog.csdn.net/qq_42837885/article/details/99191885
おすすめ