2012-09-25 4 views
1

아래 코드를 준수하십시오. 내가 아는 한 dynamic_cast는 static_cast보다 느립니다. 그것은 런타임에 타입을 평가하기 때문입니다. 여기에 typeid()와 함께 static_cast를 사용하면 동적 캐스트와 동일한 시간이 걸릴까요? dynamic_cast보다 빠릅니까? RTTI와static_cast 및 RTTI vs dynamic_cast

class Shape 
{ 
public: 
    virtual ~Shape(){} 
}; 
class Circle : public Shape{ }; 
class Square : public Shape{ }; 

정적 캐스트 :

Circle c; 
Shape* s = &c; // Upcast: normal and OK 

// More explicit but unnecessary: 
s = static_cast<Shape*>(&c); 
// (Since upcasting is such a safe and common 
// operation, the cast becomes cluttering) 

Circle* cp = 0; 
Square* sp = 0; 

// Static Navigation of class hierarchies 
// requires extra type information: 
if(typeid(s) == typeid(cp)) // C++ RTTI 
    cp = static_cast<Circle*>(s); 
if(typeid(s) == typeid(sp)) 
    sp = static_cast<Square*>(s); 
if(cp != 0) 
    cout << "It's a circle!" << endl; 
if(sp != 0) 
    cout << "It's a square!" << endl; 

동적 캐스트 :

Circle c; 
Shape* s = &c; // Upcast: normal and OK 

s = &c; 
Circle* cp = 0; 
Square* sp = 0; 
cp = dynamic_cast<Circle*>(s); 
    if(cp != 0) 
    cout << "It's a circle!" << endl; 
sp = dynamic_cast<Square*>(s); 
if(sp != 0) 
    cout << "It's a square!" << endl; 
+0

이것은 개체에 대한 포인터를 참조하는 경우에만 작동합니다. 그런 다음'typeid'는'Circle *'과'Shape *'을 다시주는 대신 동적 유형의 객체와 함께 작동합니다. –

+0

안녕하세요 Pileborg, 귀하의 제안에 감사드립니다, 나는 단지 그들 사이의 시간 차이를 알고 싶습니다. 미리 정의 된 기능으로 확인하겠습니다. – ranganath111

+0

다시 시도해보고 다시보고하십시오. –

답변

7

형식을 테스트 한 다음 static_cast을 수행하는 것이 더 빠르지 만 조작은 동등하지 않으므로 대부분 파생 유형 만 다운 캐스트 할 수 있습니다 (중간 수준은 typeid과 일치하지 않음). 더 견고하기 때문에 dynamic_cast을 사용할 것입니다 (누군가가 사용자의 유형을 확장하고 포인터를 전달하면 중단되지 않습니다).

dynamic_cast의 성능이 응용 프로그램에서 문제가되는 경우 디자인을 다시 고려해야합니다. typeid + static_castdynamic_cast보다 빠르지 만 개체의 런타임 유형을 전환하지 않아도됩니다.

1

괜찮은 컴파일러가 두 예제를 모두 동일한 코드로 최적화 할 수있을 것이라고 생각합니다. 그러나 특정 도구 체인의 결과를 측정하는 방법 밖에 없습니다.

+0

실제로 컴파일러는 런타임시 정보에 의존하는 이와 같은 것을 최적화 할 수 없습니다. (아마도이 ​​구체적인 예제로 컴파일러가 알거나 예측할 수없는 모든 것을 도입 할 수 있습니다. 'typeid' 비교는 두 포인터 사이의 단일 비교를 수행합니다. 반면에'dynamic_cast'는 상속 트리를 처리하기 때문에, 이론적으로는 이전의 것이 빠릅니다. 하지만 네, 결과를 측정해야합니다. –

+0

@SethCarnegie 필자는 컴파일러가 RTTI를 최적화 할 것이라는 것을 의미하는 것은 아니지만 매우 간단한 경우에 가능하다는 데 동의합니다. 오히려, 나는'typeid'와'static_cast'의이 사용법이 단순히'dynamic_cast'의 사용자 구현 일 뿐이라고 추론 할 수 있다고 믿습니다. 그리고 어떤 경우에도 같은 코드를 출력 할 것입니다. –

+0

이 방법으로 사용 된'static_cast'와'typeid'는'dynamic_cast'가 아닙니다.앞서 말했듯이, 그들은 완전히 다른 일을합니다. 하나는 두 가지 유형을 직접 비교하고, 다른 하나는 여러 유형을 비교합니다. 또한'dynamic_cast'는 실패시 다른 동작을합니다. 따라서 컴파일러는'static_cast' 버전을'dynamic_cast'로 변경하는 데 오류가 있습니다. –

3

이러한 코드 샘플은 논리적으로 동일하지 않습니다. 당신은 dynamic_cast이 계정에 클래스 상속을한다는 것을 잊었고, typeid()를 비교하면 상속 트리의 리프 만 비교합니다. typeid가주는 유일한 것은 "해당 객체의 실제 유형과 관련된 고유 식별자"입니다. 혼자 typeid()를 사용하면 공통베이스 포인터에 대한 캐스트가 가능한지 여부를 확인할 수 없으므로 runtimetype-of-that가 runtimetype-of-otherthing과 정확히 일치하는지 여부 만 확인할 수 있습니다.

static_cast + typeid는 일반적인 의미에서 좀 더 빠르지 만 경우에 따라서는 잘못된 대답을 줄 것이라고 생각합니다.

+0

typeid는 런타임에 객체의 실제 유형과 관련된 고유 한 식별자를 제공합니다. 그렇지 않습니까? typeid()만으로 충분하지 않습니까 ?? dynamic_cast는 런타임 검사를 수행한다고 생각합니다. 내가 틀렸어 나를 바로 잡는다. – ranganath111

+1

예, 런타임에만 작동합니다. 편집 당시에는 알 수 없으며 비교할 수있는 것이 없습니다. – quetzalcoatl

+0

@ ranganath111 : 요점은'type'을 사용하여'A','B'' 및'C'의 계층 구조를 갖는 경우 객체가 가장 파생 된 유형 'C'인지 테스트 할 수 있지만 그것은'B'입니다. 만약 당신의 코드가 실제 타입이'C'인지'C'인지를 신경 쓰지 않고 계층 구조의'B' 브랜치에있는 것이라면'dynamic_cast' 만 사용할 수 있지만'typeid'는 할 수 없습니다. 또한 typeid를 사용하면 형식을 전환하는 것이 좋지 않을 수 있습니다. 장래에 누군가가 어떤 조건에서도 일치하지 않는'D'로 계층 구조를 확장한다면. –