c+중 깊이 복사 및 쓰기 시 복사 구현 예제 코드

본 고 는 주로 c++에서 깊이 있 게 복사 하고 쓸 때 복사 하 는 것 과 관련 된 내용 을 소개 하고 여러분 에 게 참고 학습 을 제공 합 니 다.다음은 더 이상 말 하지 않 고 상세 한 소 개 를 하 겠 습 니 다.
1.얕 은 복사&깊 은 복사
얕 은 복사:구 조 를 복사 할 때 원래 내용 의 주 소 를 복사 할 클래스 에 직접 건 네 주 고 두 가지 유형 은 공동으로 한 공간 을 가리킨다.그러나 큰 결함 이 존재 한다.① s2 를 조작 하면 s1 의 내용 도 달라 진다.② 구 조 를 분석 할 때 먼저 s2 를 분석 한 다음 에 s1 을 분석 하지만 s1,s2 가 같은 공간 을 가리 키 기 때문에 한 공간의 2 차 분석 구 조 는 실 수 를 초래 할 수 있다.
딥 복사:원본 공간 크기 와 같은 공간 을 개척 하고 내용 을 복사 하여 조작 합 니 다.s2 를 조작 하 든 안 하 든 같은 크기 의 공간 과 내용 을 복사 합 니 다.
그림 은 다음 과 같다.

깊 은 복사 본 은 다음 과 같다.

#include <iostream>
using namespace std;


class String
{
public:
 String(char* str = "")
 :_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(const String& s)
 // :_str(NULL)
 //{
 // String tmp(s._str);
 // swap(_str, tmp._str);
 //}

 //****************       **************
 //String& operator=(const String& s)
 //{
 // if (this != &s)
 // {
 // delete[] _str;
 // _str = new char[strlen(s._str) + 1];
 // strcpy(_str, s._str);
 // }
 // return *this;
 //}

 //****************       **************
 String& operator=(String& s)
 {
 swap(_str, s._str);
 return *this;
 }

 //***************    ********************
 ~String()
 {
 if (_str)
 {
  delete[] _str;
 }
 }

private:
 char* _str;
};
2.쓰기 시 복사
쓰기 시 복사:하나의 계수 기 를 도입 하여 각 내용 의 공간 에 하나의 카운터 로 구성 되 어 있 습 니 다.첫 번 째 클래스 가 가리 키 는 방향 을 구성 할 때 계수 기 는 1 로 초기 화 되 었 고 그 후에 새로운 클래스 가 같은 공간 을 가리 킬 때마다 계수 기 는 가격 을 올 립 니 다.구 조 를 분석 할 때 이 공간 에 대응 하 는 계수기 가 1 인지 아 닌 지 를 판단 하고 1 이면 청소 작업 을 수행 하 며 1 이상 이면 계수기-1 이다.삭제 등 작업 이 필요 할 때 공간 을 복사 해 효율 을 높이 는 데 유리 하 다.
쓰기 1:

#include <iostream>
using namespace std;

class String
{
public:
 String(char* str = "")
 :_str(new char[strlen(str)]+1)
 , _refCount(new int(1))
 {
 strcpy(_str, str);
 }

 String(const String& str)
 : _str(str._str)
 ,_refCount(str._refCount)
 {
 (*_refCount)++;
 }

 ~String()
 {
 release();
 }

 String& operator= (const String& s)
 {
 if (_str != s._str)
 {
  release();
  _refCount = s._refCount;
  (*_refCount)++;
  _str = s._str;
 }
 return *this;
 }

 void release()
 {
 if ((*--_refCount) == 0)
 {
  delete[] _str;
  delete _refCount;
 }
 }

private:
 char* _str;
 int* _refCount;
};
단점:새로운 종 류 를 만 들 때마다 네 개의 바이트 가 더 열 려 공간 에 많은 메모리 조각 이 생 길 수 있다.
두 번 째:

class String
{
public:
 String(char* str = "")
 :_str(new char[strlen(str)+1+4])
 {
 *(int*)_str = 1;
 _str += 4;
 strcpy(_str, str);
 }

 String(const String& s)
 :_str(s._str)
 {
 ++GetCount();
 }

 ~String()
 {
 release();
 }

 String& operator=(const String& s)
 {
 if (this != &s)
 {
  realease();
  _str = s._str;
  GetCount()++;
 }
 return *this;
 }

 void release()
 {
 if (--GetCount() == 0)
 {
  _str -= 4;
  delete[] _str; 
 }
 }

 int& GetCount()
 {
 return *((int*)_str - 1);
 }

private:
 char* _str;
};
주의:카운터 가 저장 되 어 있 기 때문에str 첫 번 째 주소-4 의 주소 에 있 기 때문에 구 조 를 분석 할 때 반드시 모든 방출 에 주의 하여 메모리 누 출 을 피해 야 합 니 다.
그림 은 다음 과 같다.

총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 십시오.저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기