C++/Class 2021. 3. 20. 17:32

다형성의 기본 개념

  • 부모 클래스의 포인터로 자식 클래스의 주소를 가리키면, 부모 클래스의 인스턴스로 인식한다.

예제

  • 자식 클래스에서 멤버 함수를 오버라이딩해도, 부모 클래스의 포인터에서 접근하면 부모 클래스의 멤버 함수가 호출된다.

    #include <iostream>
    
    class Animal
    {
    protected:
      std::string    name_;
    
    public:
      Animal(const std::string & name_in)
        : name_(name_in)
      {}
    
      std::string    getName() { return name_; }
    
      void speak() const
      {
        std::cout << name_ << " ??? " << std::endl;
      }
    };
    
    class Cat : public Animal
    {
    public:
      Cat(const std::string & name_in)
        : Animal(name_in)
      {}
    
      void speak() const
      {
        std::cout << name_ << " Meow " << std::endl;
      }
    };
    
    class Dog : public Animal
    {
    public:
      Dog(const std::string & name_in)
        : Animal(name_in)
      {}
    
      void speak() const
      {
        std::cout << name_ << " Woof " << std::endl;
      }
    };
    
    int        main()
    {
      using namespace std;
    
      Animal    animal("my animal");
      Cat        cat("my cat");
      Dog        dog("my dog");
    
      animal.speak();
      cat.speak();
      dog.speak();
    
      Animal* ptr_animal1 = &cat;
      Animal* ptr_animal2 = &dog;
    
      ptr_animal1->speak();
      ptr_animal2->speak();
    }
    
    /* stdout
    my animal ???
    my cat Meow
    my dog Woof
    my cat ???
    my dog ???
    */

  • 부모 클래스의 멤버 함수를 정의할 때 virtual 키워드를 붙이면, 자식 클래스에서 오버라이딩한 멤버 함수를 사용하도록 한다.

    #include <iostream>
    
    class Animal
    {
    protected:
      std::string    name_;
    
    public:
      Animal(const std::string & name_in)
        : name_(name_in)
      {}
    
      std::string    getName() { return name_; }
    
      virtual void speak() const
      {
        std::cout << name_ << " ??? " << std::endl;
      }
    };
    
    class Cat : public Animal
    {
    public:
      Cat(const std::string & name_in)
        : Animal(name_in)
      {}
    
      void speak() const
      {
        std::cout << name_ << " Meow " << std::endl;
      }
    };
    
    class Dog : public Animal
    {
    public:
      Dog(const std::string & name_in)
        : Animal(name_in)
      {}
    
      void speak() const
      {
        std::cout << name_ << " Woof " << std::endl;
      }
    };
    
    int        main()
    {
      using namespace std;
    
      Cat    cats[] = { Cat("cat1"), Cat("cat2"), Cat("cat3"), Cat("cat4"), Cat("cat5") };
      Dog    dogs[] = { Dog("dog1"), Dog("dog2") };
    
      for (int i = 0; i < 5; ++i)
        cats[i].speak();
      for (int i = 0; i < 2; ++i)
        dogs[i].speak();
    
      cout << endl;
      Animal* my_animals[] = {&cats[0], &cats[1], &cats[2], &cats[3], &cats[4], &dogs[0], &dogs[1]};
    
      for (int i = 0; i < 7; ++i)
        my_animals[i]->speak();
    }
    
    /* stdout
    cat1 Meow
    cat2 Meow
    cat3 Meow
    cat4 Meow
    cat5 Meow
    dog1 Woof
    dog2 Woof
    
    cat1 Meow
    cat2 Meow
    cat3 Meow
    cat4 Meow
    cat5 Meow
    dog1 Woof
    dog2 Woof
    */

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

C++ Override, Final  (0) 2021.03.20
C++ 가상 함수와 다형성 (virtual)  (0) 2021.03.20
C++ 다형성 (Polymorphism)  (0) 2021.03.20
C++ 다중 상속  (0) 2021.03.20
C++ 상속받은 멤버의 접근 권한 변경  (0) 2021.03.20