class BASE {
public:
virtual ~BASE() {}
void lamp() {
cout << "\nBASE CLASS";
}
};
class DERIVED : public BASE {
public:
void fun();
};
void DERIVED::fun() {
cout << "\nDERIVED CLASS!";
}
int main() {
BASE * pbase = new DERIVED; //BASE CLASS POINTER
void * vbase = pbase; //VOID POINTER TAKING BASE POINTER
DERIVED * pder; //DERIVED CLASS POINTER
//pder = static_cast<DERIVED *>(vbase); //THIS WORKS
pder = dynamic_cast<DERIVED *>(vbase); //THIS DOESN'T
pder->lamp();
pder->fun();
return 0;
}
void*
파생 클래스 포인터에 대한 포인터 를 동적으로 캐스팅하려고 할 때마다 다음 오류가 발생합니다.
'vbase'( 'void *'유형)를 'class DERIVED *'유형으로 dynamic_cast 할 수 없습니다 (소스가 클래스에 대한 포인터가 아님).
StackOverflow를 검색하고 오류를 피하기 위해 기본 클래스에서 가상 함수를 구현하여 조언을 따랐습니다. 내가 도대체 뭘 잘못하고있는 겁니까? 이것이 가능합니까?
내 전반적인 의도는 void*
포인터를 사용하여 들어오는 모든 Object 유형을 Derived 클래스 유형으로 캐스팅하는 것 입니다. 무슨 말인지 이해해 주셨으면합니다.
예를 들면 :
void dynamicCast(void * vptr)
{
BASE * pbase = new DERIVED;
DERIVED * pder;
pder = dynamic_cast<DERIVED *>(vbase);
}
모든 유형의 포인터를 dynamicCast
함수 에 전달할 수 있어야 하며 파생 클래스 포인터로 변환되어야합니다.
디자인이나 이해 문제가 있다고 생각합니다.
으로는 할 수 없습니다 설명 dynamic_cast
A로부터 void*
.
왜? 때문에 dynamic_cast
요구 사항이 일부 런타임 타입 정보 (RTTI)가 캐스팅을 수행합니다 ( 이 링크 자세한 내용을). 에서 void*
혼자 C ++ 코드는이 정보가 어디 있는지 알 수있는 기회가 없습니다. 최소한 이러한 RTTI 정보가있는 개체에 대한 포인터를 사용하는 것입니다.
이 정보는 하나 이상의 가상 메서드를 가진 모든 클래스에 생성되고 바인딩됩니다 . 가상 방법이없는 경우이 정보는 포함되지 않습니다. 이것이 작동 하지 않는 이유입니다 .
struct A
{
};
struct B : A
{
};
int main()
{
B b;
A *a = &b;
dynamic_cast<B *>(a); // YOUR COMPILE TIME ERROR
}
해결 방법은 A에 가상 메서드를 추가하는 것입니다. 여기 에서는 일반적으로 좋은 방법이므로 가상 소멸자를 추가했습니다.
struct A
{
virtual ~A() = default;
};
struct B : A
{
};
int main()
{
B b;
A *a = &b;
dynamic_cast<B *>(a); // OK
}
또한 dynamic_cast
변환이 합법적인지 확인할 수 있습니다.
예를 들어 C 클래스를 추가 하고 다음을 확인할 수 있습니다 .
struct C
{
};
int main()
{
B b;
A *a = &b;
assert(dynamic_cast<B *>(a)!=nullptr); // OK
assert(dynamic_cast<C *>(a)==nullptr); // OK can not cast A to C
}
이러한 종류의 런타임 작업은 무료가 아닙니다. 이 트릭을 사용할 수있는 최대 속도를 검색하는 경우 :
assert(dynamic_cast<B *>(a)!=nullptr);
B* b=static_cast<B*>(a);
디버그 모드에서 모든 것이 정상인지 확인하고 -DNDEBUG
플래그를 제거하는 릴리스 모드 assert
에서static_cast
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다