2015년 6월 17일 수요일

상속 객체 복사

class CCharacter
{
protected:
char* m_name;
public:
CCharacter():m_name(0) {printf("CCharacter()\n");}
CCharacter(char* name)
  {
  m_name = new char[strlen(name)+1];
  strcpy(m_name, name);
}
CCharacter(const CCharacter& c)
{
  printf("CCharacter& c \n");
  m_name = new char[strlen(c.m_name)+1];
  strcpy(m_name, c.m_name);
}
~CCharacter() { delete[] m_name; }
CCharacter& operator=(const CCharacter& c)
{
  printf("operator=\n");
  if(this == &c) { return *this; }

  if(m_name != NULL) { delete[] m_name; }
  m_name = new char[strlen(c.m_name)+1];
  strcpy(m_name, c.m_name);
  return *this;
}

char* GetName() { return m_name; }
};


class CHighElf : public CCharacter
{
private:
int m_level;
public:
CHighElf():m_level(0) {}
CHighElf(char* name, int lv=0):CCharacter(name), m_level(lv) {}
CHighElf(const CHighElf& h):/*CCharacter(h),*/ m_level(h.m_level)
{
  //괄호 위에 있는 CCharacter(h), 이 핵심
  //이 부분이 괄호 위로 올라감으로 해서 CCharacter 기본 생성자가 호출되지 않고
  //바로 CCharacter 복사 생성자가 호출.
  //CCharacter::CCharacter(h); // 이렇게 하면 기본 생성자 호출
  //m_level = h.m_level;
}
~CHighElf() {}
CHighElf& operator=(const CHighElf& h)
 {
  //CCharacter::operator=(h);//부모 클래스의 대입연산자도 호출해 줘야한다.
  m_level = h.m_level;
  return *this;
}

const int GetLevel() { return m_level; }

void Print() { printf("name: %s  level: %d\n",m_name, m_level); }
};

int _tmain(int argc, _TCHAR* argv[])
{
//상속없는 객체의 복사, 대입
CCharacter* c1 = new CCharacter("c1");
printf("c1 name: %s\n", c1->GetName());

CCharacter* c2 = new CCharacter(*c1);
printf("c2 name: %s\n", c2->GetName());

CCharacter* c3 = new CCharacter();
*c3 = *c2;
printf("c3 name: %s\n", c3->GetName());

delete c1;
delete c2;
delete c3;

//상속 객체의 복사, 대입
printf("==========================================\n");


//CHighElf(char* name, int lv=0) 호출
//따로 지정된 것이 있다. CCharacter(char* name) 호출.
CHighElf* h1 = new CHighElf("h1");
h1->Print();//이름 h1 정확이 들어가 있다.

//CHighElf(const CHighElf& h) 호출
//따로 지정된 것이 없기에 CCharacter()호출.
CHighElf* h2 = new CHighElf(*h1);
h2->Print();//name은 복사되지 않아 NULL이다.

//대입시 CHighElf의 맴버 변수만 복사처리 하기때문에 부모클래스의 것이 누락된다.
CHighElf* h3 = new CHighElf();
*h3 = *h1;
h3->Print();//name은 복사되지 않아 NULL이다.

//해결책은 해당 복사생성자와 대입연산자 구현부에 주석처리 되어있음

delete h1;
delete h2;
delete h3;

  return 0;
}

댓글 없음:

댓글 쓰기