Programming/C C++
C++을 통해 특정 Class를 작성한 후 개발자가 다른 Class를 작성할 필요가 생겼다고 가정해 보겠습니다.

이때 새로 만들어야할 Class는 기존 Class에서 완전히 다른 개념의 Class가 아니라 단지 특정 부분만을 새로이 추가시키는 정도의 Class입니다.

예를 들어 학생의 시험성적관리를 위한 다음과 같은 기존 Class가 있습니다.

class exam{
  private:
    char name[15];
    int kuk;
 
  public:
    exam(char *nm, int a);
   
    void memberprint();
};

exam::exam(char *nm, int a)
{
  strcpy(name, nm);
 
  kuk = a;
}


이때 지금 새로이 만들어야할 Class는 단순히 영어과목만을 추가한 것이라고 가정해 보겠습니다. 이때 물론 처음부터 새롭게 Class를 작성하도 되지만 이는 "이 Class의 일부분이 다른 Class와 같다." 라는 측면에서 본다면 분명 낭비일 것입니다. 이런경우 상속(Inheritance)이라는 개념이 필요하게 됩니다.

일단 기존 Class가 exam.h라는 Header File에 선언과 정의된 부분이 있다고 가정한다면 위 Class를 활용한 Program은 다음과 같이 작성될 수 있습니다.

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

class exam{
  private:
    char name[15];
    int kuk;
 
  public:
    exam(char *nm, int a);
   
    void memberprint();
};

exam::exam(char *nm, int a)
{
  strcpy(name, nm);
 
  kuk = a;
}

void exam::memberprint()
{
  cout << "이름 : " << name << endl;
  cout << "국어 : " << kuk << endl;
}


기존 Class의 선언과 정의부분(exam.h에 저장)

#include "exam.h"
#include <iostream.h>

main()
{
  exam student("youngsoo", 90);
   
  student.memberprint();
  return 0;
}



이제 이 Program을 수정하여 기존 Class에서 상속받은 새로운 Class(영어점수 관리추가)를 작성해 보도록 하겠습니다.

#include "exam.h"
#include <iostream.h>

class exam2 : private exam{
  private:
    int eng;
  public:
    exam2(char *nm, int a, int b);
    void memberprint();
};

exam2::exam2(char *nm, int a, int b) : exam(nm, a)
{
  eng = b;
}

void exam2::memberprint()
{
  exam::memberprint();
  cout << "영어점수 : " << eng << endl;
}

main()
{
  exam2 student("youngsoo", 90, 80);
 
  student.memberprint();
  return 0;
}


먼저 #include "exam.h"는 exam Class를 불러오기 위해 선언된 것입니다.

class exam2 : private exam은 exam2라는 새로운 Class를 정의하되 exam Class를 상속받겠다는 것을 의미합니다. 이때 private는 exam Class의 각 Member를 어떻게 상속받을지 지정하는 것으로 private의 경우 exam Class에서 정의된 public Member와 proteted Member를 private의 성격으로 상속받게 됩니다.

반면 public로 상속하면 public Member를 public 성격그대로 상속받습니다.(어떤 성격으로 상속받을지와는 상관없이 본래 Class에서 private로 선언된 Member는 접근할 수 없습니다.)

이 새로운 exam2 Class는 private Member로 eng Member변수와 exam2(char *nm, int a, int b); 그리고 memberprint()를 Member함수로 갖도록 하였습니다.

class exam2 : private exam{
  private:
    int eng;
  public:
    exam2(char *nm, int a, int b);
    void memberprint();
};

그 다음엔 exam2의 생성자를 정의하는데 본래 Class의 생성자까지 포함하도록 하고 있습니다. 이 경우 exam2의 생성자를 실행할때 exam Class의 생성자를 초기화 한 후 eng = b;부분을 실행하게 됩니다.

exam2::exam2(char *nm, int a, int b) : exam(nm, a)
{
  eng = b;
}

또한 exam2 Class에서 생성자를 통해 초기화 한 값을 확인하는 함수로 memberprint() Member를 정의하였습니다.

void exam2::memberprint()
{
  exam::memberprint();
  cout << "영어점수 : " << eng << endl;
}

여기에서 알 수 있는것은 본래 Class와 상속받는 Class에서 같은 이름으로 정의가 되는 경우 :: 연산자를 통해 해당 Member가 어느 Class에 속하는지를 구분해야 한다는 것입니다.

위에서 정의된 memberprint() Member는 exam2에서 정의되었지만 exam Class에도 있습니다. 만일 ::연사자를 사용하지 않고 그냥 memberprint()라고만 하면 어느 Class의 memberprint()함수를 불러올지 알 수 없을 것입니다.

exam2의 memberprint()함수 안에서는 exam::memberprint()를 통해서 exam Class의 memberprint() Member 함수를 불러오도록 하고 있습니다. 이는 memberprint() Member함수가 exam Class내에서 public로 정의되었기 때문에 가능한 것입니다.

따라서 만일 memberprint()함수가 private나 proteted로 정의되었다면 위와같이 불러오는것은 불가능합니다.

void exam2::memberprint()
{
  cout << "국어점수 : " << kuk << endl;
  cout << "영어점수 : " << eng << endl;
}

kuk는 exam Class에서 private로 선언되었습니다. 따라서 위와 같이 작성하는 것은 오류입니다.(kuk이 public라면 문제가 없습니다.)


참고 :
본래 Class에서 public Member를 불러올때에는 exam::memberprint()처럼 ::연산자를 사용하지 않고 memberprint()라고 할 수도 있으나 위 예제에서는 그렇게 할 수 없습니다.

이유는 memberprint()함수가 exam2 Class에서도 정의되었으므로 결국 어느 Class를 지정하는지 명확히 해줄 필요가 생긴것입니다.

따라서 이 경우 ::연산자를 사용해 어떤 Class인지를 구분해 줘야 합니다.

물론 Class를 상속한다고 해서 원래의 Class를 사용할 수 없는것은 아닙니다. 본래 Class부분과 상속된 Class부분 모두 Program내에서 구현할 수 있습니다.

#include "exam.h"
#include <iostream.h>

class exam2 : private exam{
  private:
    int eng;
  public:
    exam2(char *nm, int a, int b);
    void memberprint();
};

exam2::exam2(char *nm, int a, int b) : exam(nm, a)
{
  eng = b;
}

void exam2::memberprint()
{
  exam::memberprint();
  cout << "영어점수 : " << eng << endl;
}

main()
{
  exam2 student("youngsoo", 90, 80);
  exam student2("sooyoung", 70);
 
  student.memberprint();
  student2.memberprint();
  return 0;
}


상속된 exam2 Class와 본래의 exam Class의 사용


Class를 상속할때 하나의 Class에서만 상속이 가능한것은 아닙니다. 필요하다면 두개, 세개의 Class에서 동시에 상속받을 수도 있는데 이런 경우를 다중상속이라고 합니다.

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

class exam{
  private:
    char name[15];
    int kuk;
 
  public:
    exam(char *nm, int a);
   
    void memberprint();
};

class exam2{
  private:
    char name[15];
    int eng;
 
  public:
    exam2(char *nm, int a);
   
    void memberprint();
};

exam::exam(char *nm, int a)
{
  strcpy(name, nm);
 
  kuk = a;
}

void exam::memberprint()
{
  cout << "이름 : " << name << endl;
  cout << "국어 : " << kuk << endl;
}

exam2::exam2(char *nm, int a)
{
  strcpy(name, nm);
 
  eng = a;
}

void exam2::memberprint()
{
  cout << "이름 : " << name << endl;
  cout << "영어 : " << eng << endl;
}


exam.h를 수정하여 새로은 exam2라는 새로운 Class를 정의하였습니다.

#include "exam.h"
#include <iostream.h>

class exam3 : private exam, private exam2{
  private:
    int soc;
  public:
    exam3(char *nm, int a, int b);
    void memberprint();
};

exam3::exam3(char *nm, int a, int b) : exam(nm, a), exam2(nm, a)
{
  soc = b;
}

void exam3::memberprint()
{
  exam::memberprint();
  exam2::memberprint();
  cout << "사회점수 : " << soc << endl;
}

main()
{
  exam3 student("youngsoo", 90, 80);
 
  student.memberprint();
  return 0;
}


exam2 Class를 정의할때 exam과 exam2 Class에서 다중 상속되도록 하였습니다.

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

[C, C++] Object간의 연산과 Operator  (0) 2010.02.24
[C, C++] Microsoft C, C++ Compiler  (0) 2010.01.22
[C, C++] Class 상속  (0) 2010.01.13
[C, C++] 함수작성및 Data전달  (0) 2010.01.07
C언어 함수사용 예제 Souce  (0) 2010.01.06
[C, C++] Pointer  (0) 2010.01.05
0 0