2009-04-13 5 views
0

다음 구문의 의미는 무엇입니까?C++ 구문 질문

typedef void* hMyClass; //typedef as a handle or reference 
hMyClass f = &something; 
const MyClass& foo = static_cast<MyClass&>(*f); 
foo.bar(); 

답변

2

static_cast는 다른 하나의 참조 형으로 변환하는 경우, 변환중인 것은 (동적 캐스트와는 달리) 실제로 대상 유형의 인스턴스라는 시스템이 실제로 있는지 확인하려고하지 않음을 의미 .

따라서 컴파일러는 hMyClass에 포함되어 있고 무언가에서 가져온 주소가 실제로 MyClass의 인스턴스를 포함하고 있으며 예측할 수없는 것들에 대한 전적인 책임을지고 있음을 알 수 있습니다. 당신이 틀렸다면 일어날 것입니다.

"무언가"의 유형은 무엇입니까? 거기에 오류가있을 수도 있습니다. &이 필요할 수 있습니다.

1

이것은 실제로 유효하지 않습니다. 2 행의 변수가 아닌 유형에 값을 지정합니다.

0

void *는 일반적으로 일반 포인터로 사용됩니다. C#에서

이 같은 유사 할 것입니다 :

object o = new XmlDocument(); 

객체 O = 새 목록();

그러나 C++에서는 유형 안전이 거의 적용되지 않습니다. IIRC, static_cast는 런타임 유형 검사가 수행되지 않으므로 (cast)와 동일합니다.

+0

일반적으로 템플릿은 일반 컬렉션에 사용됩니다. 요즘 빈 포인터가 필요한 장소는 거의 없습니다. 빈 포인터는 일반적으로 핸들과 같은 '익명'유형에 사용됩니다. 일반적으로 적용 가능한 경우 템플리트 기반 솔루션이 선호됩니다. –

+0

static_cast <>는 C 스타일 (캐스트)과 완전히 다릅니다. C 스타일의 형변환은 상황에 따라 static_cast <>, reinterpret_cast <>, const_cast <> 또는 임의의 조합으로 작동 할 수 있습니다. –

+0

@ Dan : 나는 런타임 점검이 이루어지지 않았다고 진술했다. (캐스트) 및 static_cast doest는 RTTI를 포함하지 않습니다. @ Jasper : 예제가 모호합니다. C#에서 모든 클래스를 개체 참조에 할당 할 수 있습니다. C++에서 void *를 사용하여이 작업을 수행하고 있으므로 모든 객체 유형을 일반 포인터에 할당 할 수 있습니다. – Alan

0

본질적으로 누군가가 MyClass 포인터를 void 포인터에 저장하여 콜백에 전달할 가능성이 높습니다. 이 코드는 아마도 콜백되었으므로이를 다시 캐스팅하여 MyClass로 사용할 수 있습니다.

또한 구문 오류가있어 eagerwishes 메모가 있습니다.

0

이 문맥이 더 이상없는 것을 "정확하게"말하기는 어렵습니다. 나는 당신이 다른 누군가의 코드에 대해 작업하고 있다고 가정하고, 보여주고있는 라인들은 여러 기능들에 흩어져있는 것으로 보입니다.

코드 의도에 대한 가장 좋은 추측은 제 3 자 코드/라이브러리를 처리하는 메커니즘이라는 것입니다. C++에서는 자신의 타입을 가진 타사 라이브러리를 사용하는 것이 일반적입니다. 해당 라이브러리가 작성하고 소유 한 데이터를 일시적으로 보유해야하는 경우 라이브러리가 유형에 대해 알지 못하더라도 라이브러리가 데이터에 액세스 할 수있는 방법이 필요합니다. 한 가지 예가 콜백/이벤트 기능입니다. 라이브러리에서 이벤트가 발생할 때 비동기 적으로 알리면 함수 포인터와 사용자 정의 데이터를 제공하여 함수 호출시 처리 방법을 알 수 있도록해야합니다. 라이브러리는 일반적으로이 사용자 제공 데이터에 void * 포인터를 사용합니다. C++에서 사용자 제공 데이터에 대한 객체 인스턴스를 전달한 다음 해당 객체에 위임하여 콜백을 처리하는 것이 일반적입니다. 코드는 다음과 같습니다.

// 3rd-party library API 
typedef void (*PingNotifyPtr)(void*); 
void NotifyOnPing(PingNotifyPtr, void* userData); 
// User Code 
void MyNotify(void* myData) 
{ 
    MyClass* ptr = (MyClass*)myData; 
    // do something with ptr 
} 
void Main() 
{ 
    MyClass *pClass = new MyClass(); 
    NotifyOnPing(&MyNotify, pClass); 
    // the callback is now armed with all the data it needs. 
} 

많은 라이브러리는 "void *"인수를 선언하여이를 수행합니다. 이것은 일부 메모리 위치에 대한 원시 포인터입니다. 그 위치, 정수, 클래스 인스턴스, 문자열 등에서 무엇이든있을 수 있습니다. 타사 라이브러리는 해당 포인터를 유지하고 어떤 시점에서 다시 코드로 돌아갑니다.

예제 코드의 세 번째 줄은 void * 포인터를 가져 와서 클래스 인스턴스에 대한 참조로 캐스팅하는 것입니다. C++ 참조는 NULL이 될 수없고 값 구문을 사용한다는 점을 제외하면 포인터와 유사합니다 ('.'연산자 대신'-> '연산자). 예제 코드의 네 번째 줄은 재구성 된 클래스 인스턴스에서 메서드를 사용합니다.

어쨌든 4 행의 코드가 모두 코드베이스에서 연속적이면 해당 코드는 누군가가 C++을 모르는 것을 의미합니다.

(*((const MyClass*)something)).Foo(); 

행운을 빕니다 : 당신이 값 구문을 선호하는 경우,

((const MyClass*)something)->Foo(); 

또는 다음은 한 줄에 동일한 코드를 할 수있는 컴팩트 방법이있다!