본문 바로가기

Programming/C C++

[C, C++] Class구현시 생성자와 소멸자 활용

Class사용시에는 Class의 Object를 생성한 후 각 Member함수를 호출하여 Member변수의 값을 설정합니다.

이와는 달리 Class의 생성자는 Object생성과 동시에 원하는 Member변수를 초기화 할 수 있습니다.

#include <iostream.h>
#include <string.h>

class exam{
  private:
    char name[15];
    int kuk;
    int mat;
    int eng;
 
  public:
    exam(char *nm, int k, int m, int e);
   
    void name_input(char *nm);
    void memberprint();
   
    int kuk_input(int pt);
    int mat_input(int pt);
    int eng_input(int pt);
};

exam::exam(char *nm, int k, int m, int e)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = e;
}

void exam::name_input(char *nm)
{
  strcpy(name, nm);
}

int exam::kuk_input(int pt)
{
  int ptp = pt;
 
  if (pt >= 90)
    ptp = pt + 3;
 
  kuk = pt;
 
  return ptp;
}

int exam::mat_input(int pt)
{
  int ptp = pt;
 
  if (pt >= 90)
    ptp = pt + 3;
 
  mat = pt;
 
  return ptp;
}

int exam::eng_input(int pt)
{
  int ptp = pt;
 
  if (pt >= 90)
    ptp = pt + 3;
 
  eng = pt;
 
  return ptp;
}

void exam::memberprint()
{
  cout << "학생이름 : " << name << endl << endl;
  cout << "국어점수 : " << kuk << endl;
  cout << "수학점수 : " << mat << endl;
  cout << "영어점수 : " << eng << endl;
}

main()
{
  exam student("young soo", 90, 100, 80);
 
  student.memberprint();
  return 0;
}


Class안에 exam(char *nm, int k, int m, int e); 으로 생성자를 선언하고 main안에서 exam student("young soo", 90, 100, 80); 구문을 통해 생성자로 초기값을 설정합니다.

생성자의 선언은 Class이름과 동일하게 하고 인수를 설정하여 어떠한 Member에 값을 설정할지를 지정하면 됩니다. 생성자의 본체도 Class이름으로 다음과 같이 작성되어 해당 Member에 대해 초기화를 수행하도록 합니다.
exam::exam(char *nm, int k, int m, int e)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = e;
}

생성자는 초기화 전용입니다. 따라서 return을 통해 값을 반환할 수 없습니다. 반환값없는 전용이므로 이 생성자함수에 void나 int처럼 return형식을 지정하는 것 자체가 무의미한 것입니다.

생성자를 통해 값을 초기화 하려면 Class의 Object생성시 바로 인수를 건네주도록 합니다. 그러면 자동으로 생성자가 호출되어 해당 Class에 대한 초기화처리를 하게 됩니다.

exam student("young soo", 90, 100, 80);

소멸자는 Class이름앞에 ~문자를 붙여 선언하는 것으로 이 소멸자는 Class의 Member함수를 호출하고 그 함수를 빠져나올때 자동으로 호출되는 특징을 가지고 있습니다.

#include <iostream.h>
#include <string.h>
class exam{
  private:
    char name[15];
 
  public:
    exam(char *nm);
    ~exam();
   
    void name_input(char *nm);
    void memberprint();
};

exam::exam(char *nm)
{
  strcpy(name, nm);
}

exam::~exam()
{
  cout << "소멸자가 호출됨" << endl;
}

void exam::name_input(char *nm)
{
  strcpy(name, nm);
}

void exam::memberprint()
{
  cout << "학생이름 : " << name << endl << endl;
}

main()
{
  exam student("young soo");
 
  student.memberprint();
  return 0;
}


Class안에 ~exam();으로 소멸자를 선언하였습니다. 이 소멸자는 Class내의 함수가 호출되고 난 후마다 자동 호출됩니다.


소멸자는 어떤값도 반환하지 않고 또 어떠한 인수도 전달하지 않습니다. 또한 소멸자를 정의하는 함수부분에는 개발자가 Class의 함수호출이 이루어지고 난 다음에 필요한 부분을 작성하기만 하면 되는 것입니다.

1. 생성자 Overloaded

C++에서의 함수는 Overloaded가 가능합니다. 즉, 같은 이름의 함수에 다른 인수의 특성에 따라 다른처리를 행하는 것이 가능한 것입니다.

이러한 Overloaded는 일반 함수뿐만 아니라 생성자에도 적용할 수 있습니다. 물론 생성자에 Overloaded를 선언하는 방법도 일반함수와 다를게 없습니다.

#include <iostream.h>
#include <string.h>

class exam{
  private:
    char name[15];
    int kuk;
    int mat;
    int eng;
 
  public:
    exam();
    exam(char *nm, int k, int m);
    exam(char *nm, int k, int m, int e);
   
    void memberprint();
};

exam::exam()
{
  strcpy(name, "noname");
 
  kuk = 0;
  mat = 0;
  eng = 0;
}

exam::exam(char *nm, int k, int m)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = 200;
}

exam::exam(char *nm, int k, int m, int e)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = e;
}

void exam::memberprint()
{
  cout << "학생이름 : " << name << endl;
  cout << "국어점수 : " << kuk << endl;
  cout << "수학점수 : " << mat << endl;
  cout << "영어점수 : " << eng << endl << endl;
}

main()
{
  exam student_fir;
  student_fir.memberprint();
 
  exam student_sec("young soo", 90, 100);
  student_sec.memberprint();
 
  exam student_thr("soo young", 90, 100, 50);
  student_thr.memberprint();
  return 0;
}


Class에서 exam세개를 선언하였으며 각각의 함수마다 인수를 틀리게 하여 Overloaded화 하였습니다. Class에서 생성자를 Overloaded로 선언하면 각 함수에 맞는 정의도 다음과 같이 해주어야 합니다.

exam::exam()
{
  strcpy(name, "noname");
 
  kuk = 0;
  mat = 0;
  eng = 0;
}

exam::exam(char *nm, int k, int m)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = 200;
}

exam::exam(char *nm, int k, int m, int e)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = e;
}


이렇게 하면 생성자를 호출할때마다 해당 인수에 따라서 다른 형태로 초기화를 수행할 것입니다.

주의할 것은 Class의 Object를 생성할때 다른 Overloaded 생성자를 호출하고자 한다면 다음과 같이 다른 이름의 Object를 사용해야 한다는 것입니다.

exam student_fir;
student_fir.memberprint();
 
exam student_sec("young soo", 90, 100);
student_sec.memberprint();
 
exam student_thr("soo young", 90, 100, 50);
student_thr.memberprint();


만일 Class의 Object가 배열로 생성되면 []를 이용해 몇번째 배열의 Object에서 Member를 호출할지를 지정해야 하는데 이때 위와 같은 생성자의 특징을 이용하면 {}를 사용해 배열의 Member를 한꺼번에 초기화 할 수도 있습니다.

#include <iostream.h>
#include <string.h>

class exam{
  private:
    char name[15];
    int kuk;
    int mat;
    int eng;
 
  public:
    exam(char *nm, int k, int m, int e);
   
    void memberprint();
};

exam::exam(char *nm, int k, int m, int e)
{
  strcpy(name, nm);
 
  kuk = k;
  mat = m;
  eng = e;
}

void exam::memberprint()
{
  cout << "학생이름 : " << name << endl;
  cout << "국어점수 : " << kuk << endl;
  cout << "수학점수 : " << mat << endl;
  cout << "영어점수 : " << eng << endl << endl;
}

main()
{
  exam student[2] = {
    exam("soo young", 90, 100, 50),
    exam("young soo", 59, 65, 88)
  };
 
  student[0].memberprint();
  student[1].memberprint();
  return 0;
}


exam Class의 student Object를 2로 하여 2개의 배열로 Object가 생성되도록 하였습니다.

이후 초기화는 {와 }사이에 묶어 exam("soo young", 90, 100, 50)과 exam("young soo", 59, 65, 88)으로 각각의 배열에 이름과 점수를 초기화 합니다.

'Programming > C C++' 카테고리의 다른 글

[Visual C++] 관련 라이브러리  (0) 2012.06.21
표준 Library 함수 - Memory 관련 함수  (0) 2011.06.16
[C, C++] Class구현시 생성자와 소멸자 활용  (0) 2011.06.01
[C, C++] Class  (0) 2011.05.25
[C, C++] cout 서식지정  (0) 2011.04.14
[C, C++] 구조체  (1) 2011.04.13