string 기초 시뮬레이션 깊이 복사 실현

string 구현
  • string(const char* str)
  • string(string&string)
  • operator=(string &string)
  • ~string()은 왜 깊은 복사가 있습니까?

  • 얕은 복사


    비트 복제라고도 합니다. 즉, 리소스를 비트별로 복제하는 것입니다. 객체에서 리소스를 관리하면 결국 여러 객체가 같은 리소스를 공유하게 되고 한 객체가 제거되면 리소스가 풀리게 됩니다. 이때 다른 객체는 리소스가 풀렸는지 모르고 다시 풀리게 됩니다. 예를 들어
    char c[] = "ada";
    char *d = c;
    

    그래서 딥 카피가 생겼어요.
    #include 
    #include 
    #include 
    #pragma warning(disable:4996)
    using namespace std;
    namespace bit
    {
    	class string
    	{
    	public:
    		string(const char*  str= "")
    		{
    			if (str == nullptr)
    			{
    				_str = new char[1];
    				(*_str) = '\0';
    			}
    			else
    			{
    				_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 (&S !=  this)
    			//{
    			//	
    			//	
    			//	char*_pstr = new char[strlen(S._str) + 1];
    			//	delete[] _str;// delete[]
    			//	strcpy(_pstr, S._str);
    			//	_str = _pstr;
    			//	return *this;// 
    			//}
    			string strtmp(S);
    			swap(strtmp._str, _str);// 
    			return *this;
    		}
    
    		~string()
    		{
    			if (_str)
    			{
    				delete[] _str;
    				_str = nullptr;
    			}
    		}
    	private:
    
    		char* _str;
    	};
    
    
    }
    
    int main()
    {
    	bit::string a("hello world");
    	bit::string b(a);
    	bit::string c;
    	c = a;
    	b = a;
    	
    }
    

    a, b, c의 모든 자원은 독립적이기 때문에 같은 자원을 중복 방출하지 않는다.
    얕은 복사도 자원의 중복 방출을 방지할 수 있는 방법이 있습니까?스마트 포인터를 참고하여 현재 얼마나 많은 포인터가 이 자원을 가리키는지 표시하고 이 포인터가 0이면 이 자원을 방출할 수 있습니다.이 표시에 대해 두 가지 방법이 있을 수 있습니다. 하나는 정적 변수count를 설정하는 것이고, 두 번째는 int 바늘 변수count를 설정하는 것입니다.각 포인터는 자원을 가리키며 +1.또 어떤 상황을 감안하여 첫 번째 방안을 포기하면 관심 있는 독자들은 왜 그런지 생각해 볼 수 있다.
    
    namespace bit
    {
    	class string
    	{
    	public:
    		string(const char* str = "")
    		{
    			if (str == nullptr)
    			{
    				_str = new char[1];
    				(*_str) = '\0';
    
    			}
    			else
    			{
    				_str = new char[strlen(str) + 1];
    				strcpy(_str, str);
    			}
    			*count = 1;
    		}
    		string(const string& S)
    		{
    			if (_str != nullptr && --(*count) == 0)
    			{
    				delete[] _str;
    				delete count;
    				_str = nullptr;
    				count = nullptr;
    			}
    			_str = S._str;
    			count = S.count;
    			(*count)++;
    			//cout << *count;
    
    		}
    
    		string& operator=(const string& S)
    		{
    			if (_str != nullptr && --(*count) == 0)
    			{
    				delete[] _str;
    				delete count;
    				_str = nullptr;
    				count = nullptr;
    			}
    			_str = S._str;
    			count = S.count;
    			(*count)++;// *count++,
    			
    			return *this;
    		}
    		char& operator[](int i)
    		{
    			if (*count > 1)//? 1
    			{
    				bit::string S(_str);
    				Swap(S);
    			}
    			return _str[i];
    		}
    
    		char& operator[](int i) const
    		{
    			return _str[i];
    		}
    
    		~string()
    		{
    			if (_str && --(*count) == 0)
    			{
    				delete[] _str;
    				delete count;
    				_str = nullptr;
    				count = nullptr;
    			}
    		}
    		void Swap(bit::string S)
    		{
    			swap(_str,S._str);
    			swap(count, S.count);
    
    		}
    	private:
    
    		char* _str;
    		int* count = new int(0);
    	};
    
    
    }
    

    그러나 위의 코드는 매우 큰 결함이 있다. 그 중의 한 자원을 수정하면 다른 자원에 영향을 줄 수 있기 때문에 우리는 쓸 때 이 자원을 분리할 수 있다. 즉, 쓸 때 복사하고 Copy On Write는 []를 다시 불러올 수 있다. *count의 값이 2보다 크면 분리한다.

    좋은 웹페이지 즐겨찾기