문제

내가 가지고 있다고 가정 해 봅시다 베이스 수업과 몇몇 파생 클래스. 다음과 같은 글을 쓸 필요없이 파생 클래스 중 하나에 객체를 캐스팅 할 수있는 방법이 있습니까?


string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast< Derived1*>(object);
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast < Derived2*>(object);
}
...
else {
  ...
}
도움이 되었습니까?

해결책

하지 않다.

다형성을 읽으십시오. 거의 모든 "동적 캐스트"상황은 구현되기 위해 고군분투하는 다형성의 예입니다.

역동적 인 캐스트에서 어떤 결정을 내 렸는지 이미 이루어졌습니다. 실제 작업을 서브 클래스에 위임하십시오.

당신은 당신의 예에서 가장 중요한 부분을 제외했습니다. 유용하고 다형성 작업.

string typename = typeid(*object).name();
if(typename == "Derived1") {
   Derived1 *d1 = static_cast< Derived1*>(object);
   d1->doSomethingUseful();
}
else if(typename == "Derived2") {
   Derived2 *d2 = static_cast < Derived2*>(object);
   d2->doSomethingUseful();
}
...
else {
  ...
}

모든 서브 클래스가 dosomethinguseful을 구현하는 경우, 이것은 훨씬 간단합니다. 다형성.

object->doSomethingUseful();

다른 팁

당신이 사용할 수있는 dynamic_cast 그리고 null을 테스트하지만 나는입니다 강하게 대신 코드를 리팩토링하는 것을 고려하십시오.

서브 클래스 특정 처리가 필요한 경우 템플릿 메소드 도움이 될 수 있지만, 당신이 무엇을 달성하려고하는지 모르면 모호한 추측 일뿐입니다.

Derived1* d1 = dynamic_cast< Derived1* >(object);
if (d1 == NULL)
{
    Derived2* d2 = dynamic_cast< Derived2* >(object);
    //etc
}

SmartPointer 유형에 다음 방법이 있습니다. C# 'IS'및 'AS'를 시뮬레이션합니다.

template< class Y > bool is() const throw()
    {return !null() && dynamic_cast< Y* >(ptr) != NULL;}
template< class Y > Y* as() const throw()
    {return null() ? NULL : dynamic_cast< Y* >(ptr);}

당신은 이것을 사용하여 할 수 있습니다 dynamic_cast, EG :

if ( Derived1* d1 = dynamic_cast<Derived1*>(object) ) {
    // object points to a Derived1
    d1->foo();
}
else if ( Derived2* d2 = dynamic_cast<Derived2*>(object) ) {
    // object points to a Derived2
    d2->bar();
}
else {
    // etc.
}

그러나 다른 사람들이 말했듯이, 이와 같은 코드는 나쁜 디자인을 나타낼 수 있으며 일반적으로 사용해야합니다. 가상 기능 다형성 행동을 구현합니다.

일반적으로 이것은 나쁜 디자인의 표시입니다. 왜 이것을해야합니까? 필요하지 않도록 재 설계 할 수 있습니다.

정확히 무엇을 성취하려고합니까? 내 경험상 이와 같은 것은 나쁜 디자인의 표시입니다. 객체 지향 디자인의 목표는이 불필요한 것과 같은 것을 만드는 것이기 때문에 클래스 계층 구조를 다시 평가하십시오.

정확한 이름 () 형식이 지정되지 않기 때문에 예제는 포트가 아닙니다. 당신은 연속을 시도 할 수 있습니다 dynamic_cast에스. Dynamic_cast 잘못된 유형으로 캐스팅하면 널 포인터를 반환합니다. 그러나 이와 같은 Typeswitch를하고 있다면 디자인에 문제가 있습니다.

Dynamic_cast는 갈 길이라고 생각하지만, 캐스트 될 객체가 일부 타사 모듈에 의해 제공 될 수 있기 때문에 이것이 가능한 모든 조건에 대한 나쁜 디자인이라고 생각하지 않습니다. 응용 프로그램 작성자가 지식이없는 플러그인에 의해 개체가 생성되었다고 가정 해 봅시다. 또한 특정 플러그인은 DERived1 (이전 버전)을 생성 할 수 있습니다. 유형 객체 또는 파생물 2 (새 버전) 유형 객체를 생성 할 수 있습니다. 플러그인 인터페이스는 버전 특정 작업을 수행하도록 설계되지 않았을 수도 있습니다. 단지 객체를 생성하므로 응용 프로그램이 적절한 캐스팅/실행을 보장하기 위해 이러한 종류의 검사를 수행해야합니다. 그 후, 우리는 객체를 안전하게 호출 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top