2015년 6월 18일 목요일

operator= 의 자기대입 방어

#include <memory>

class CBitMap
{
public:
CBitMap() { printf("BitMap()\n"); }
CBitMap(const CBitMap& b)
{ printf("CBitMap(const CBitMap& b)\n"); }
};

class CCharacter
{
private:
CBitMap* m_pb;

public:
CCharacter()
{
  printf("CCharacter()\n");
  m_pb = new CBitMap();
}

CCharacter(const CBitMap& b)
{
  printf("CCharacter(const BitMap& bp)\n");
  m_pb = new CBitMap(b);
  memcpy(m_pb, &b, sizeof(b));
}

void Swap(CCharacter& c)
{
  CBitMap* pbOrg = m_pb;
m_pb = new CBitMap(*c.m_pb);
c.m_pb = pbOrg;
}

CCharacter& operator=(const CCharacter& c)
{
  printf("operator=\n");

  //자기대입에 대한 방어
  //1안) 비교
  /*if( this == &c )//자기 자신이라면
  { return *this; }

  delete m_pb;//아무 조건 없이 지움
  m_pb = new CBitMap(*c.m_pb);//만약 여기서 예외가 발생한다면? m_pb는 망함;
  return *this;*/

  ///////////////////////////////////////////////////////////////////////////////////
  //2안) 원래 값을 따로 저장해 둔 후 삭제, new의 fail에 대처하는 자세
  /*CBitMap* pbOrg = m_pb;
  CBitMap* temp = new CBitMap(*c.m_pb);
  if(temp == NULL)
  { return *this; }
  m_pb = temp;
  delete pbOrg;*/

  ///////////////////////////////////////////////////////////////////////////////////
  //3안) 복사 후 맞 바꾸기(copy and swap)
  /*CCharacter temp(*c.m_pb);
  Swap(temp);
  delete temp.m_pb;
  return *this;*/
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
CBitMap b;
CCharacter c1(b);

CCharacter c2;
c2 = c1;

return 0;
}

댓글 없음:

댓글 쓰기