void *에 대한 합법적 인 사용이 있습니까?
void*
C ++에서를 합법적으로 사용 합니까? 아니면 C가 있었기 때문에 도입 되었습니까?
내 생각을 요약하자면 :
입력 : 여러 입력 유형을 허용하려면 함수와 메서드를 오버로드 할 수 있습니다. 대신 공통 기본 클래스 또는 템플릿을 정의 할 수 있습니다 (답변에 언급 해 주셔서 감사합니다). 두 경우 모두 코드가 더 설명적이고 오류 발생 가능성이 적습니다 (기본 클래스가 정상적인 방식으로 구현 된 경우).
출력 : void*
알려진 기본 클래스에서 파생 된 것과는 반대로 수신 하고 싶은 상황을 생각할 수 없습니다 .
내가 의미하는 바를 명확히하기 위해 :에 대한 유스 케이스가 있는지 구체적으로 묻는 것이 아니라 최선의 선택 또는 사용 가능한 선택 void*
이있는 경우가 있는지 여부 를 구체적으로 묻지 않습니다 void*
. 아래의 여러 사람들이 완벽하게 답변했습니다.
void*
최소한 ::operator new
(또한 모든 operator new
...) 의 결과 및 malloc
배치 new
연산자 의 인수로 필요합니다 .
void*
모든 포인터 유형의 공통 상위 유형으로 생각할 수 있습니다. 따라서 그것은 정확히에 대한 포인터를 의미하는 것이 아니라 void
어떤 것에 대한 포인터를 의미합니다.
BTW, 관련되지 않은 여러 전역 변수에 대한 일부 데이터를 유지하려면 std::map<void*,int> score;
global int x;
and double y;
and std::string s;
do score[&x]=1;
and score[&y]=2;
and 를 선언 한 후 일부 를 사용할 수 있습니다.score[&z]=3;
memset
void*
주소를 원함 (가장 일반적인 주소)
또한 POSIX 시스템에는 dlsym이 있으며 반환 유형은 분명히void*
을 사용하는 데는 여러 가지 이유가 있으며 void*
가장 일반적인 세 가지는 다음과 같습니다.
void*
인터페이스에서 사용하는 C 라이브러리와 상호 작용- 유형 삭제
- 형식화되지 않은 메모리 표시
역순 void*
으로 char*
(또는 변형) 대신 (3)을 사용 하여 형식화되지 않은 메모리를 표시 하면 우발적 인 포인터 산술을 방지하는 데 도움이됩니다. 사용 가능한 작업이 거의 void*
없으므로 일반적으로 유용하기 전에 캐스팅이 필요합니다. 물론 char*
앨리어싱에 문제가없는 것과 매우 비슷 합니다.
Type-erasure (2)는 템플릿과 함께 C ++에서 계속 사용됩니다.
- 비 제네릭 코드는 바이너리 팽창을 줄이는 데 도움이되며 일반 코드에서도 콜드 경로에 유용합니다.
- 비 제네릭 코드는 때때로 저장을 위해 필요합니다.
std::function
그리고 당연히 당신이 다루는 인터페이스가 void*
(1) 을 사용할 때 , 당신은 선택의 여지가 거의 없습니다.
어 그래. 심지어 C ++에서 때때로 우리는 함께 갈 void *
것이 아니라 template<class T*>
때로는 템플릿 확장에서 추가 코드가 너무 많은 무게 때문이다.
일반적으로 유형의 실제 구현으로 사용하고 템플릿 유형은 여기에서 상속하고 캐스트를 래핑합니다.
또한 사용자 지정 슬랩 할당 자 (운영자 새 구현)는 void *
. 이것이 g ++ void *
가 마치 크기 1 인 것처럼 포인터 산술을 허용하는 확장을 추가 한 이유 중 하나입니다 .
입력 : 여러 입력 유형을 허용하려면 함수와 메서드를 오버로드 할 수 있습니다.
진실.
또는 공통 기본 클래스를 정의 할 수 있습니다.
이것은 부분적으로 사실입니다. 공통 기본 클래스, 인터페이스 또는 이와 유사한 것을 정의 할 수 없다면 어떻게 될까요? 이를 정의하려면 소스 코드에 대한 액세스 권한이 필요하며 이는 종종 불가능합니다.
템플릿에 대해서는 언급하지 않았습니다. 그러나 템플릿은 다형성에 도움이되지 않습니다. 즉, 컴파일 타임에 알려진 정적 유형에서 작동합니다.
void*
가장 낮은 공통 분모로 간주 될 수 있습니다. C ++에서는 일반적으로 필요하지 않습니다. (i) 본질적으로 많은 작업을 수행 할 수없고 (ii) 거의 항상 더 나은 솔루션이 있기 때문입니다.
또한 일반적으로 다른 구체적인 유형으로 변환하게됩니다. 그렇기 때문에 char *
순수한 데이터 블록이 아닌 C 스타일 문자열을 기대하고 있음을 나타낼 수 있지만 일반적으로 더 좋습니다. 이것이 다른 포인터 유형에서 암시 적 캐스트를 허용하기 때문에 void*
그보다 나은 이유 입니다 char*
.
당신은 약간의 데이터를 받고, 그것으로 작업하고, 출력을 만들어야합니다. 이를 달성하려면 작업중인 데이터를 알아야합니다. 그렇지 않으면 원래 해결했던 문제가 아닌 다른 문제가 발생합니다. 예를 들어 많은 언어 void*
에는 문제가 없습니다.
또 다른 합법적 인 사용
When printing pointer addresses with functions like printf
the pointer shall have void*
type and, therefore, you may need a cast to void
*
Yes, it is as useful as any other thing in the language.
As an example, you can use it to erase the type of a class that you are able to statically cast to the right type when needed, in order to have a minimal and flexible interface.
In that response there is an example of use that should give you an idea.
I copy and paste it below for the sake of clarity:
class Dispatcher {
Dispatcher() { }
template<class C, void(C::*M)() = C::receive>
static void invoke(void *instance) {
(static_cast<C*>(instance)->*M)();
}
public:
template<class C, void(C::*M)() = &C::receive>
static Dispatcher create(C *instance) {
Dispatcher d;
d.fn = &invoke<C, M>;
d.instance = instance;
return d;
}
void operator()() {
(fn)(instance);
}
private:
using Fn = void(*)(void *);
Fn fn;
void *instance;
};
Obviously, this is only one of the bunch of uses of void*
.
Interfacing with an external library function which returns a pointer. Here is one for an Ada application.
extern "C" { void* ada_function();}
void* m_status_ptr = ada_function();
This returns a pointer to whatever it was Ada wanted to tell you about. You don't have to do anything fancy with it, you can give it back to Ada to do the next thing. In fact disentangling an Ada pointer in C++ is non-trivial.
In short, C++ as a strict language (not taking into account C relics like malloc()) requires void* since it has no common parent of all possible types. Unlike ObjC, for example, which has object.
The first thing that occurs to my mind (which I suspect is a concrete case of a couple of the answers above) is the capability to pass an object instance to a threadproc in Windows.
I've got a couple of C++ classes which need to do this, they have worker thread implementations and the LPVOID parameter in the CreateThread() API gets an address of a static method implementation in the class so the worker thread can do the work with a specific instance of the class. Simple static cast back in the threadproc yields the instance to work with, allowing each instantiated object to have a worker thread from a single static method implementation.
In case of multiple inheritance, if you need to get a pointer to the first byte of a memory chunk occupied by an object, you may dynamic_cast
to void*
.
참고URL : https://stackoverflow.com/questions/34272717/is-there-a-legitimate-use-for-void
'developer tip' 카테고리의 다른 글
명령 줄에서 Gradle로 인수를 전달하는 방법 (0) | 2020.09.14 |
---|---|
JSDoc에서 매개 변수 또는 반환 값으로 객체 배열을 지정하는 방법은 무엇입니까? (0) | 2020.09.14 |
자바 스크립트를 사용하여 테이블 만들기 (0) | 2020.09.13 |
Vagrant 상자를 찾을 수 없거나 원격 카탈로그에서 액세스 할 수 없습니다. 호환되지 않는 컬 버전 (0) | 2020.09.13 |
Eclipse의 Android 장치 선택기에 Android 장치가 표시되지 않는 이유는 무엇입니까? (0) | 2020.09.13 |