Steady Blog

21. 상속 part 2 ---정리 필요함. 본문

Programing/C++

21. 상속 part 2 ---정리 필요함.

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

*상속 part 2

 

1. 상속 사용하는 법

  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 함수 사용


 // 부모에서 자식을 동적할때와 자식이 자기 자신을 동적할때의 차이점은 virtual함수의 사용의 차이다.

그렇다면 동적할당을 하는 장점은 무엇일까?

 3. 바인딩.

  바인딩이란 함수 호출과 실제 함수를 연결하는 방법을 말한다. 바인딩은 정적 바인딩과 동적 바인딩으로 나뉜다.

기본적으로 c+++는 기복적으로 정적바인딩을 수행한다. 동적 바인딩을 하려면 virtual키워드를 사용해서 함수를 정의해야 한다.

 3-1 정적 바인딩

  정적 바인딩은 컴파일 타임에 호출될 함수를 결정한다. 객체나 포인터의 타입을 보고 호출할 함수를 결정한다.

3-2 동적바인딩

동적 바인딩은 런타임 (실행중)에 호출될 함수를 결정한다. 호출 함수 결정은 객체의 가사함수 table를 사용한다.

4.가상함수   ----<정리 필요.>

c++의 함수는 정적 바인딩을 한다. 즉, 컴파일 타임에 타입을 보고 호출할 함수를 결정한다.

그러나 virtual 키워드

 


<연습 예제>

3번과 4번의 차이를 알아보자!  - 4번

class Living
{
public:
 void Live() {cout<<"살아 있다.\n";}

 virtual void Breath() {cout<<"Living : 산소로 호흡한다.\n";}
 virtual void Walk() {cout<<"Living : 네발로 걷는다.\n";}

};
class Animal0 : public Living
{
public:
 void Breath() {cout<<"산소로 호흡한다.\n";}
 void Move() {cout<<"움직인다.\n";}
};
class Mammalia :public Animal0
{
public:
 void BringingUp() {cout<<"젖으로 새끼를 양육한다.\n";}
 void Walk() {cout<<"네발로 걷는다.\n";}
};
void ch10_08()
{
 Living *p1 = new Living;
 Living *p2 = new Animal0; //부모에서 자식 동적
 Living *p3 = new Mammalia; //부모에서 자식의 자식 동적
        //그러나 쓸수 있는건 부모클래스의 Live()밖에 없음.
        //이때 필요한게 Virtual 함수.
 p1->Live();
 p2->Live();
 p3->Live();

 p2->Breath();
}

 

   virtual , 함수가 없을때 결과 값

 

  함수만 있을때 결과값

  virtual 이 있을때 결과값

 

 

 

 

 


<연습 예제>

3번과 4번의 차이를 알아보자! - 3번

class Animal
{
public:
     void Speak() {cout<<"동물의 울음소리를 출력하세요. \n";}
     void Animal::Walk() {cout<<"네발로 걷는다.\n";}  

//walk()라고 표현할수도 있다. Animal::을 붙인 이유는  Anumal::붙여서도 사용할수 있다는 것을 표현 한 것임.
};
class Dog : public Animal
{
public:
     void Speak() {cout<<"멍멍~!\n";}
};

class Cat : public Animal
{
public:
     void Speak() {cout<<"야옹~!\n";}
};

class Pig : public Animal
{
public:
     void Speak() {cout<<"꿀꿀~!\n";}
};
class Duck : public Animal
{
public:
     void Speak() {cout<<"괙꽥~!\n";}
     void Walk() {cout<<"두발로 걷는다.\n";}
};
enum AnimalName {DOG = 1,CAT,PIG,DUCK};
#define EXIT 5
void ch10_09()
{
     Dog *pDog = NULL;
     Cat *pCat = NULL;
     Pig *pPig = NULL;
     Duck *pDuck = NULL;

     while(1)
     {
          cout<<"\n 1.Dog 2.Cat 3.Pig 4.Duck 5.Exit\n";
          cout<<"Choice : [ ]\b\b";
          int choice;
          cin>>choice;

          switch(choice)
          {
              case DOG : pDog = new Dog;     //자식클래스 동적할당
                             pDog ->Speak();
                             pDog ->Walk();
                             delete pDog;
                             break;
              case CAT : pCat = new Cat;      //자식클래스 동적할당
                             pCat ->Speak();
                             pCat ->Walk();
                             delete pCat;
                             break;
              case PIG : pPig = new Pig;       //자식클래스 동적할당
                             pPig ->Speak();
                             pPig ->Walk();
                             delete pPig;
                             break;
              case DUCK : pDuck = new Duck;    //자식클래스 동적할당
                             pDuck ->Speak();
                             pDuck ->Walk();
                             delete pDog;
                             break;  
              case EXIT: cout<<"Eng PGM\n"; exit(0);
              default: cout<<"Select Error\n"; continue;
          }

 
    }

}


//부모 class의 속성 의  virtual 을 붙여줘야함.

class Animal
{
public:
     virtual void Speak() {cout<<"동물의 울음소리를 출력하세요. \n";}
     virtual void Walk() {cout<<"네발로 걷는다.\n";}
};

// 위의 Class와 같다.  

void ch10_10()
{
     Animal *pAni = NULL;

     while (1)
     {
          cout<<"\n 1.Dog 2.Cat 3.Pig 4.Duck 5.Exit\n";
          cout<<"Choice : [ ]\b\b";
          int choice;
          cin>>choice;

          switch(choice)
          {
              case DOG : pAni = new Dog; break;
              case CAT : pAni = new Cat; break;
              case PIG : pAni = new Pig; break;
              case DUCK : pAni = new Duck; break;
              case EXIT : cout<<"Eng PGM\n"; exit(0);
  
              default: cout<<"Select Error\n"; continue;
           }
           pAni->Speak();
           pAni->Walk();
           delete pAni;

      }
}

 

실행 되는 순서

    1.  case에서 Dog 동적 할당 받음

    2. 부모 클래스가서 virtual 함수을 발견

    3. Dog 함수 가서 virtual void speak 함수 찾음 =>없음

    4. 부모 클래스가서 virtual void speak 함수 찾음 => 있음 => 결과 나옴.

    5. Dog 함수 가서 virtual void Walk 함수 찾음 =>없음

    6. 부모 클래스가서 virtual void Walk 함수 찾음 => 있음 => 결과 나옴.

 

- 결과 값은 바로 위의 예제 결과와 같다 -


<연습문제>

 

class DrawDate
{
private:
     int height;
     char outchar;
public:
     void set_height(int a) { height = a;}
     void set_outchar(char b) {outchar = b;}
     int get_height() {return height;}
     char get_outchar() {return outchar;}
     virtual void draw() 
     {
          printf("부모클래스여~\n");
     }
};
class IsoTriangle : public DrawDate
{
public:
     void draw()
     {
          int i,j;
          int h = get_height();
          char c = get_outchar();
          for(i=1;i<=h;i++)
          {
               for(j=1;j<=i;j++)
               {
                    printf("%c",c);
               }
               printf("\n");
          }                                      // 이등변 삼각형 자료구조
     }
};
class Pyramid : public DrawDate
{
public:
     void draw()
     {
          int i,j;
          int h = get_height();
          char c = get_outchar();
          for(i=1;i<=h;i++)
          {
               for(j=1;j<=h-i;j++)
               {
                    printf(" ");
               }
               for(j=1;j<=2*i-1;j++)
               {
                    printf("%c",c);
               }
               printf("\n");
          }                                   // 피라미드 자료구조
     }
};
void exam_1()
{
     DrawDate *pa;
     pa = new IsoTriangle;
     pa->set_height(10);
     pa->set_outchar('x');
     pa->draw();
     delete pa;

     Pyramid *pa1;


     pa1 = new Pyramid;
     pa1->set_height(10);
     pa1->set_outchar('x');
     pa1->draw();
     delete pa1;
}

 

 

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

23. 예외 처리  (0) 2012.09.04
22. 연산자 오버로딩 - 정리 필요.  (0) 2012.09.04
20. 상속  (0) 2012.09.04
19. 정적변수  (0) 2012.09.04
18. const변수  (0) 2012.09.04