Steady Blog

20. 상속 본문

Programing/C++

20. 상속

우유먹고쑥 2012. 9. 4. 00:02

*상속


      - private 는 상속 불가능

1. 상속 받는 법

class AAA                            // 부모 클래스, Base Class

{

       public:

       void ex()

       {

       }

};         

                                         

class BBB : public AAA           //자식 클래스, Derived Class

{                                          //   public = 접근 지정자 , AAA 상속받고 싶은 클래스명

       public:

       void ex1()

       {

       }

}

 

2. 사용하는 법

  1) BBB bb;               //일반변수 형태

      bb.ex();

      bb.ex1();

 

   2) BBB *pb = &bb;    //함수의 매개변수로 사용할 때

       pb->ex();

       pb->ex1();

 

   3) BBB *pc;             // 동적 할당 - 자식 클래스

       pb = new BBB;

       pc->ex();

       pc->ex1();

       delete pc;

 

    4) AAA *pd;            // 동적 할당 - 부모 클래스 

       pd = new BBB;

       pd->ex();

       pd->ex1();

       delete pd;

            => Virtual 함수 사용


 * 상속을 받아서 쓰는 이유.

      1) A is B 관계가 성립 되면 상속.

         => 사람은 학생이다 (애매함)

             학생은 사람이다. (참)    

             즉, 부모 클래스는 = 사람 / 학생은 자식 클래스      (학생<사람  == 자식<부모)를 의미 

 

      2) Upgrade 와 Update를 쉽게 한다.

  


< 연습문제>

class base
{
protected:
     int i,j;
public:
     void set(int a, int b) { i=a; j=b;}
     void show_ij() {cout<<"\n i = "<<i<<", j = "<<j<<endl;}
};
class derived : private base   // : public base
{
     int k;
    public:
     derived(int x) {set(1,2); k=x;}
     void show_k() { show_ij();cout<<" k = "<<k<<endl;}  
};
void ch10_02()
{
     derived ob(3);
   
// ob.set(1,2);

    // ob.show_ij();
  
   ob.show_k();
}

 

private :  상속시 private 에서만 사용 할수 있다. 단. private가 소속되어 있는 클래스일 경우는

              간접참조가 가능하다. 하지만 간접참조가 아니라 직접참조는 불가능 하다.

protected : 상속시 상속 받은 클래스까지 사용이 가능하다.

               상속 받은 자식 클래스가 아닌 다른 곳에서 사용은 불가능 하다.

public: 전 구간에서 함수/변수 등의 사용이 가능하다.


 <연습예제>

생성자 이용하기.

 

 class AAA
{
public:
     AAA() {cout<<"AAA() call"<<endl;}
     AAA(int j) {cout<<"AAA(int j) call"<<endl;}
};
class BBB : public AAA
{
public:
     BBB()    //  : AAA() 이 자동 컴파일 됨.
     {cout<<"BBB() call"<<endl;}
     BBB(int j) //  : AAA() 이 자동 컴파일 됨. 그래서 결과 값에도 int j가 아님 

                  // :AAA(j) or AAA(10) 을 넣으면 AAA(int j) call 이 나타남.
     {cout<<"BBB(int j) call"<<endl;}
};
void ch10_04()
{
     cout<<"객체 1 생성"<<endl;
     BBB bbb1;
     cout<<"객체 2 생성"<<endl;
     BBB bbb2(10);
     cout<<sizeof(bbb2)<<endl;
}

 

<결과 값> 

 

 

 


<연습 문제>

 생성자와 소멸자

class point
{
     int xp,yp;
public:
     point()
     {
      cout<<"기본 클래스의 생성자 \n";
      xp=yp=0;
     }
     ~point()
     {
      cout<<"기본 클래스의 소멸자 \n";
     }
     void set_xy(int x, int y) {xp =x,yp=y;}
     int get_x() {return xp;}
     int get_y() {return yp;}
};
class Circle : public point
{
     float r;
public:
     Circle(float d)
     {
          cout<<"파생 클래스의 생성자 \n";
          r=d;
     }
     ~Circle() { cout<<"파생 클래스의 소멸자 \n";}
     float area() {return (3.14*r*r);}
};
void ch10_05()

{
     Circle c(7.6);
     c.set_xy(10,20);
     cout<<"\n원의 중심점 : x = "<<c.get_x();
     cout<<",y = "<<c.get_y()<<endl;
     cout<<"원의 면적 : "<<c.area()<<endl;
}

 

 

 

 

 


<연습예제>

 const를 이용한 상속   

class AAA1
{
     int age;
     char name[20];
public:
     int GetAge() const {return age;}
     const char* GetName() const {return name;}     // 주소를 return 하기 때문에 char* 앞에 const 붙음
     AAA1(int a =1, char *n = "noname")
     {
          age = a;
          strcpy(name,n);
     }
};
class BBB1 : public AAA1
{
     char major[20];
public:
     BBB1(int a, char *n, char *m) : AAA1(a,n)
     {
          strcpy(major,m);
     }
     const char* GetMajor() const {return major;}   // 주소를 return 하기 때문에 char* 앞에 const 붙음
     void showDate() const
     {
          cout<<"이름 : "<<GetName()<<endl;
          cout<<"나이 : "<<GetAge()<<endl;
          cout<<"전공 : "<<GetMajor()<<endl;
     }
};
void ch10_06()
{
     BBB1 bbb(20,"Rhee","Computer");
     bbb.showDate();
}

 

 

 

 


<연습예제>

오버 라이딩

class Member
{
protected:
 char *name, *id;
public:
 Member(char* NAME,char *ID)
 {
  name = new char[strlen(NAME)+1]; strcpy(name, NAME);

//strlen()함수의 동작 원리 궁금합니다. NAME은 주소값인데 주소로 동작되는지?
  id = new char[strlen(ID)+1]; strcpy(id,ID);   

//strlen() 문자 길이 구하는 함수?
 }
 void print()
 {
  cout<<"이름 : "<<name<<endl;
  cout<<"주민등록번호 : "<<id<<endl;
 }
 ~Member() {delete []name; delete []id;}
};
class CallBonus : public Member
{
 int this_month, special, accumulation;
public:
 CallBonus(char *a, char *b, int c, int d, int e) : Member(a,b)  

 {
  this_month = c, special = d, accumulation = e;
 }
 void print()
 {
  Member::print();  

// 부모클래스와 자식클래스의 함수 이름이 같을 경우 Member::print()처럼 자식에서 호출 시켜야 함.
  cout<<"당월 : "<<this_month<<endl;
  cout<<"특별 : "<<special<<endl;
  cout<<"누적 : "<<accumulation<<endl;
 
 }
};   //함수 overwritting
void main()
{
 CallBonus ob("SJK","111111-1234567",200,100,1000);
 ob.print();  // 처음부터 부모 클래스의 함수를 호출 하고 싶으면 ob.Member::print(); 처럼 사용하면 됨.
}

 

 


<연습예제>

다중상속

 

class AAA2
{
public:
    void String1()
    {cout<<"AAA2::String1"<<endl;}

};
class BBB2
{
public:
    void String2()
    {cout<<"BBB2::String2"<<endl;}
};
class CCC2 : public AAA2, public BBB2     //여러 개의 부모클래스를 상속 받음.
{
public:
    void ShowString()
    {

        String1();
        String2();

     }
};
void ch10_08()
{
    CCC2 ccc;
    ccc.ShowString();
}

 

 

 

 #다중 상속을 받을때 주의점

    함수의 이름이 같을 경우 => 접근을 지정해 주면된다

ex) String()이라는 함수가 2개 있을 때  -> A::String() 이나 B::String()으로 쓰면 된다.  

class AAA2
{
public:
    void String()
    {cout<<"AAA2::String1"<<endl;}

};
class BBB2
{
public:
    void String()
    {cout<<"BBB2::String2"<<endl;}
};
class CCC2 : public AAA2, public BBB2     //여러 개의 부모클래스를 상속 받음.
{
public:
    void ShowString()
    {

        AAA2::String();         AAA2로 접근을 지정했다.
        BBB2::String();         BBB2
로 접근을 지정했다.

     }
};
void ch10_08()
{
    CCC2 ccc;
    ccc.ShowString();
}


<연습 문제>

  상속을 통해 삼각형, 사각형 넓이 구하기
class Area

protected:
 double height,bottom;
public:
 void setarea(double a, double b)
 {
  height = a;
  bottom = b;
 }
};
class rectangle : public Area
{
public:
 double getarea()
 {
  double i;
  i = height*bottom;
  return i;
 }
};

class triangle : public Area
{
public:
 double getarea()
 {
  double i;
  i = (height*bottom)/2;
  return i;
 }
};

void ch10_test_1()
{
 rectangle r;
 triangle t;
 r.setarea(10.5, 20.5);
 t.setarea(5.0, 7.0);
 cout<<r.getarea()<<endl;
 cout<<t.getarea()<<endl;
}

 


<연습문제>

 

class Human
{
     char *name;
     int age;
public:
     void SetName(char *n, int _age)
     {
          name = new char[strlen(n)+1];
          strcpy(name,n);
          age = _age;
     }
     char* GetName()
     {
          return name;
     }
     int GetAge()
     {
          return age;
     }
     ~Human()

    {

        delete []name;

    }
};
class Student : public Human
{
private:
     int st_Num, score;
public:
     void SetStudent(char *_name, int age, int _St_num, int _Score) 
     {
          SetName(_name,age);
          st_Num = _St_num;
          score = _Score;
     }
     void ShowStudent()
     {
          cout<<"이름 : "<<GetName()<<endl;
          cout<<"나이 : "<<GetAge()<<endl;
          cout<<"학번 : "<<st_Num<<endl;
          cout<<"성적 : "<<score<<endl<<endl;
     }

};
void ch10_test_2()
{
     Student s1,s2,s3;
     s1.SetStudent("아무나",25,1111,100);
     s2.SetStudent("장동건",27,1112,90);
     s3.SetStudent("김태희",32,1113,50);


     s1.ShowStudent();
     s2.ShowStudent();
     s3.ShowStudent();
}

 

 

 

 

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

22. 연산자 오버로딩 - 정리 필요.  (0) 2012.09.04
21. 상속 part 2 ---정리 필요함.  (0) 2012.09.04
19. 정적변수  (0) 2012.09.04
18. const변수  (0) 2012.09.04
17. 생성자, 소멸자  (0) 2012.09.04