C++에서 String 류 시 뮬 레이 션 실현 및 딥 복사 얕 은 복사

C++에서 String 류 시 뮬 레이 션 실현 및 딥 복사 얕 은 복사
C 언어 에서/C++에 서 는 문자열 이 광범 위 하 게 응용 되 는 형식 이자 기본 적 인 유형 입 니 다.C 언어 는 문자열 을 직접 처리 하지 않 고 문자 포인터 와 문자열 배열 로 작 동 합 니 다.C+에 서 는 표준 라 이브 러 리 가 문자열 의 종 류 를 봉인 하여 사용 할 수 있 습 니 다.필요 한\#inlcude헤더 파일 을 사용 합 니 다.우 리 는 간단 한 String 류 를 실현 하 는 것 을 스스로 모 의 할 수 있다.
String 류 를 모 의 실현 하 는 과정 에서 깊 은 복사 와 얕 은 복사 문제 가 발생 할 수 밖 에 없 으 므 로 다음은 깊 은 복사 와 얕 은 복사 에 대해 소개 합 니 다.깊 은 복사,얕 은 복사 란 쉽게 말 하면 얕 은 복사 가 간단하게 값 을 복사 하 는 것 이다.한 대상 으로 다른 대상 을 초기 화하 고 구성원 만 복사 하 며 자원 을 복사 하지 않 아 두 대상 이 같은 자원 을 동시에 가리 키 게 한다.한편,깊 은 복사 본 은 자원 과 값 을 한 조각 복사 하 는 것 이다.이때 두 대상 은 각각 자원 을 점용 한다.비록 값 이 같 지만 서로 영향 을 주지 않 는 다.
다음은 코드 를 통 해 비교 합 니 다.

//    
class String { 
public: 
  String(const char* s = "") 
  { 
    if (NULL == s) { 
      _pStr = new char[1]; 
      *_pStr = '\0'; 
    } 
    else { 
      _pStr = new char[strlen(s) + 1]; 
      strcpy(_pStr, s); 
    } 
  } 
  String(const String& s) 
  { 
    _pStr = s._pStr; 
  } 
  String& operator=(const String& s) 
  { 
    if (this != &s) { 
      _pStr = s._pStr; 
    } 
    return *this; 
  } 
  ~String() 
  { 
    if (NULL != _pStr) { 
      delete[] _pStr; 
      _pStr = NULL; 
    } 
  } 
 
private: 
  char* _pStr; 
}; 


//    
class String { 
public: 
  String(const char* s = "") 
  { 
    if (NULL == s) { 
      _pStr = new char[1]; 
      *_pStr = '\0'; 
    } 
    else { 
      _pStr = new char[strlen(s) + 1]; 
      strcpy(_pStr, s); 
    } 
  } 
  String(const String& s) : _pStr(new char[strlen(s._pStr) + 1]) 
  { 
    strcpy(_pStr, s._pStr); 
  } 
  String& operator=(const String& s) 
  { 
    if (this != &s) { //      s                      
      char* temp = new char[strlen(s._pStr) + 1];//                  
      strcpy(temp, s._pStr); 
      delete[] _pStr; 
      _pStr = NULL; 
      _pStr = temp; 
    } 
    return *this; 
  } 
  ~String() 
  { 
    if (NULL != _pStr) { 
      delete[] _pStr; 
      _pStr = NULL; 
    } 
  } 
private: 
  char* _pStr; 
}; 


그림 을 통 해 알 수 있 듯 이 얕 은 복사 로 인해 여러 대상 이 하나의 공간 을 가리 키 지만 마지막 으로 구 조 를 분석 할 때 예 를 들 어 c 가 먼저 공간 을 방출 하고 a,b 는 공간 을 방출 해 야 한 다 는 것 을 모 르 면 같은 메모 리 를 반복 적 으로 방출 하 는 오류 가 발생 할 수 있다.이 를 위해 우 리 는 개인 구성원 에 int*를 추가 하 는 등 얕 은 복사 본 을 최적화 할 수 있다.
 pCount 는 하나의 공간 이 몇 개의 대상 에 의 해 점용 되 었 는 지 표시 합 니 다.하나의 대상 만 점용 할 때 분석 구 조 를 하면 공간 을 방출 할 수 있 습 니 다.그렇지 않 으 면*pCount-만 사용 할 수 있 습 니 다.

//     --       String ,           
class String { 
public: 
  String(const char* s = "") : _pCount(new int(1)) 
  { 
    if (NULL == s) { 
      _pStr = new char[1]; 
      *_pStr = '\0'; 
    } 
    else { 
      _pStr = new char[strlen(s) + 1]; 
      strcpy(_pStr, s); 
    } 
  } 
  String(const String& s) 
  { 
    _pStr = s._pStr; 
    _pCount = s._pCount; 
    (*_pCount)++; 
  } 
  String& operator=(const String& s) 
  { 
    if (this != &s) { 
      if (--(*_pCount) == 0) { 
        delete[] _pStr; 
        delete _pCount; 
      } 
      _pStr = s._pStr; 
      _pCount = s._pCount; 
      (*_pCount)++; 
    } 
    return *this; 
  } 
  ~String() 
  { 
    if (NULL != _pStr && --(*_pCount) == 0) { 
      delete[] _pStr; 
      delete _pCount; 
    } 
    _pCount = NULL; 
    _pStr = NULL; 
  } 
 
private: 
  char* _pStr; 
  int* _pCount; 
}; 
마지막 으로 깊이 복사 한 간결 한 버 전 을 제시 하고 swap 를 호출 하여 조작 을 간소화 합 니 다.코드 는 다음 과 같 습 니 다.

//         
class String { 
public: 
  String(const char* s = "") 
  { 
    if (NULL == s) { 
      _pStr = new char[1]; 
      *_pStr = '\0'; 
    } 
    else { 
      _pStr = new char[strlen(s) + 1]; 
      strcpy(_pStr, s); 
    } 
  } 
  String(String& s) :_pStr(NULL)//   _pStr   ,           
  { 
    String temp(s._pStr); 
    swap(_pStr, temp._pStr); 
  } 
  String& operator=(String& s) 
  { 
    if (this != &s) {  
      swap(_pStr, s._pStr); 
    } 
    return *this; 
  } 
  ~String() 
  { 
    if (NULL != _pStr) { 
      delete[] _pStr; 
      _pStr = NULL; 
    } 
  } 
private: 
  char* _pStr; 
}; 


궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 의 커 뮤 니 티 에 가서 토론 을 교류 하 세 요.읽 어 주 셔 서 감사합니다. 도움 이 되 셨 으 면 좋 겠 습 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기