C++/Class 2021. 3. 21. 23:54

동적 형변환 (Dynamic Casting)

  • dynamic_cast는 캐스팅이 실패하면 nullptr를 반환한다.

예제

  • 간단한 예제

    #include <iostream>
    
    class Base
    {
    public:
      int    i_ = 0;
    
      virtual void print()
      {
        std::cout << "I'm Base\n";
      }
    };
    
    class Derived1 : public Base
    {
    public:
      int    j_ = 1024;
    
      virtual void print() override
      {
        std::cout << "I'm Derived\n";
      }
    };
    
    int            main()
    {
      using namespace std;
    
      Derived1    d1;
      Base*        base = &d1;
    
      d1.j_ *= 2;
    
      auto*        base_to_d1 = dynamic_cast<Derived1*>(base);
      cout << base_to_d1->j_ << endl;
      base_to_d1->j_ /= 8;
    
      cout << d1.j_ << endl;
    }
    
    /* stdout
    2048
    256
    */

  • 캐스팅 실패 예제

    #include <iostream>
    
    class Base
    {
    public:
      int    i_ = 0;
    
      virtual void print()
      {
        std::cout << "I'm Base\n";
      }
    };
    
    class Derived1 : public Base
    {
    public:
      int    j_ = 1024;
    
      virtual void print() override
      {
        std::cout << "I'm Derived\n";
      }
    };
    
    class Derived2 : public Base
    {
    public:
      std::string    name_ = "Dr. Two";
    
      virtual void print() override
      {
        std::cout << "I'm Derived\n";
      }
    };
    
    int            main()
    {
      using namespace std;
    
      Derived1    d1;
      Base*        base = &d1;
    
      d1.j_ *= 2;
    
      auto*        base_to_d1 = dynamic_cast<Derived2*>(base);
      if (base_to_d1 != nullptr)
        base_to_d1->print();
      else
        cout << "Failed to cast\n";
    }
    
    /* stdout
    Failed to cast
    */

정적 형변환 (Static Casting)

  • 최대한 변환되도록 캐스팅한다.

  • 위의 경우 가급적 Dynamic Casting을 사용하는게 안전하다.

    #include <iostream>
    
    class Base
    {
    public:
      int    i_ = 0;
    
      virtual void print()
      {
        std::cout << "I'm Base\n";
      }
    };
    
    class Derived1 : public Base
    {
    public:
      int    j_ = 1024;
    
      virtual void print() override
      {
        std::cout << "I'm Derived\n";
      }
    };
    
    class Derived2 : public Base
    {
    public:
      std::string    name_ = "Dr. Two";
    
      virtual void print() override
      {
        std::cout << "I'm Derived\n";
      }
    };
    
    int            main()
    {
      using namespace std;
    
      Derived1    d1;
      Base*        base = &d1;
    
      d1.j_ *= 2;
    
      auto*        base_to_d1 = static_cast<Derived2*>(base);
      if (base_to_d1 != nullptr)
        base_to_d1->print();
      else
        cout << "Failed to cast\n";
    }
    
    /* stdout
    I'm Derived
    */