핸들은 일종의 포인터이지만 그렇지 않다고 들었습니다. 그러면 객체 자체가 아닌 객체에 대한 참조를 유지할 수 있습니다. 더 자세한 설명은 무엇입니까?
답변:
핸들은 정수 인덱스에서 커널 공간의 리소스에 대한 포인터에 이르기까지 무엇이든 될 수 있습니다. 아이디어는 리소스의 추상화를 제공하므로 리소스를 사용하기 위해 리소스 자체에 대해 많이 알 필요가 없다는 것입니다.
예를 들어 Win32 API의 HWND는 Window의 핸들입니다. 그 자체로는 쓸모가 없습니다. 정보를 수집 할 수 없습니다. 그러나 올바른 API 함수에 전달하면 다양한 트릭을 수행 할 수 있습니다. 내부적으로는 HWND를 GUI의 창 표에 대한 색인으로 생각할 수 있습니다 (반드시 구현 방법은 아닐 수 있지만 마법은 의미가 있습니다).
편집 : 질문에서 구체적으로 무엇을 요구했는지 100 % 확실하지 않습니다. 이것은 주로 순수한 C / C ++에 대한 것입니다.
핸들은 가시적 유형이 첨부되지 않은 포인터 또는 인덱스입니다. 일반적으로 다음과 같은 내용이 표시됩니다.
typedef void* HANDLE;
HANDLE myHandleToSomething = CreateSomething();
따라서 코드에서 HANDLE을 불투명 값으로 전달하면됩니다.
객체를 사용하는 코드에서 포인터를 실제 구조 유형으로 캐스트하고이를 사용합니다.
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
또는 배열 / 벡터에 대한 인덱스로 사용합니다.
int doSomething(HANDLE s, int a, int b) {
int index = (int)s;
try {
Something& something = vecSomething[index];
return something.doit(a, b);
} catch (boundscheck& e) {
throw SomethingException(INVALID_HANDLE);
}
}
핸들 은 일반적으로 일부 엔티티를 참조하는 방법이라는 점에서 일종의 포인터입니다.
포인터가 핸들의 한 유형이라고 말하는 것이 더 정확할 것이지만 모든 핸들이 포인터는 아닙니다.
예를 들어 핸들은 메모리 테이블에 대한 일부 인덱스 일 수도 있으며, 이는 자체적으로 일부 개체에 대한 포인터를 포함하는 항목에 해당합니다.
핵심은 "핸들"이있을 때 그 핸들이 실제로 식별하는 것을 식별하는 방법을 알거나 신경 쓰지 않는다는 것입니다. 당신이 알아야 할 것은 그것이하는 것뿐입니다.
또한 "정확히 핸들이 무엇인지"에 대한 단일 답변이 없다는 것도 분명해야합니다. 동일한 시스템에서도 다른 것에 대한 핸들은 "내부에서"다른 방식으로 구현 될 수 있기 때문입니다. 그러나 이러한 차이점에 대해 걱정할 필요는 없습니다.
C ++ / CLI에서 핸들은 GC 힙에있는 개체에 대한 포인터입니다. (관리되지 않는) C ++ 힙에 개체를 만드는 것은 다음을 사용하여 수행 new
되며 new
식 의 결과 는 "일반"포인터입니다. 관리 개체는 식을 사용하여 GC (관리) 힙에 할당됩니다 gcnew
. 결과는 핸들이됩니다. 핸들에서 포인터 산술을 할 수 없습니다. 당신은 핸들을 자유롭게하지 않습니다. GC에서 처리합니다. 또한 GC는 관리되는 힙에서 개체를 자유롭게 재배치하고 프로그램이 실행되는 동안 새 위치를 가리 키도록 핸들을 업데이트 할 수 있습니다.
이것은 Pimpl 관용구라고도 하는 Handle-Body-Idiom 의 맥락에서 나타납니다 . 실제 데이터를 다른 클래스 객체로 유지함으로써 라이브러리의 ABI (바이너리 인터페이스)를 동일하게 유지할 수 있습니다.이 객체는 해당 클래스에 위임하는 함수로 구성된 "핸들"객체에있는 포인터에 의해 참조됩니다. " 몸".
두 개체의 일정 시간 및 예외 안전 스왑을 활성화하는 것도 유용합니다. 이를 위해서는 body 객체를 가리키는 포인터 만 바꿔야합니다.