2013-02-19 2 views
3

내가 아는 한, C++의 void 포인터 은 무엇이든 가리킬 수 있습니다. 일종의 상속을 사용하지 않고 솔루션을 개발하려는 경우이 방법이 유용 할 것입니다. 그러나 내가 알고 싶은 문제는이 방법에 성능상의 단점이 있는지 여부입니다.C++에서 void 포인터의 단점

+4

어떤 성능 단점? 그것은 다른 유형에 대한 포인터와 같은 포인터 일뿐입니다. 구현에 대한 설명에서 C 방법을 사용하여 C++ 문제를 해결하려고 시도하는 것 같습니다. 당신이 상속을 원한다면'void * '가 아닌 상속을 사용하십시오. –

+3

주요한 문제는 정확하게 되돌리기 위해 실제로 가리키고있는 것을 알아내는 것입니다. 그리고 당신이 그 잘못을 범하면 즉시 버그를 발견하면 행운입니다. – aschepler

+3

성능상의 단점은 없지만 모든 유형 정보를 잃어 버리고 따라서 유형 안전성을 잃게됩니다. 이는 컴파일러가 다른 방법으로 오류를 찾아 낼 수 없으며 런타임에 오류가 발생한다는 것을 의미합니다 (정의되지 않은 버그 및 추적하기 어려운 버그라고 생각하십시오). – Angew

답변

9

가장 큰 단점은 void 포인터를 사용하면 컴파일러가 형식 검사를 수행 할 수 없게된다는 것입니다. 특히 객체 지향 원칙을 지원하는 언어에서는 무효 포인터를 많이 사용하는 것이 이상하다고 생각합니다.

일부 다형성 동작을 모방하기 위해 C에서 void 포인터를 찾을 가능성이 있지만 동일한 형식 안전 문제가 있습니다.

+1

컴파일러의 관점을 지적하기 위해 +1 – LihO

0

다른 종류의 포인터와 달리 void 포인터를 사용할 때 왜 성능 문제가 있는지 알 수 없습니다. 나는 안전에 더 관심이있을 것이다. 당신은 무효 포인터를 포기하고있다.

1

void*은 무엇이든 가리킬 수 있습니다. 나는 당신이 어떤 함수에 void* 포인터를 전달에 대해 생각하는 경우, 그것은 사용되는 방법에 대해 이미 생각

상속의 일종을 사용하지 않고 솔루션을 개발하려는 경우 (나를 위해) 매우 유용 할 수 있습니다 . 이 객체에 대한 메소드를 호출하거나 멤버에 액세스하려면 어쨌든 객체의 유형을 알아야합니다.

void* 정말로 사용해야하는 경우에만 사용하십시오. 좀 더 일반적인 방법으로 객체를 다루는 방법을 찾고 있다면 적절한 객체 지향 디자인을 찾으십시오. void* 포인터가있을 때 알 수있는 것은 "메모리에이 주소에 무언가가 있습니다"라는 것입니다., 그 이상입니다.

void* 포인터를 사용하는 성능은 다른 포인터와 동일합니다. 안전, 이해도하고 또한 우려해야 확장 및 코드의 유지 보수 관련과.

1

void*이 다른 유형의 포인터보다 크거나 다른 형식의 플랫폼이있을 수 있으므로 void*의 캐스트가 실제 변환 코드가됩니다. 공용 (x86, ARM) 하드웨어에서는 그런 경우가 아니므로 void*의 성능 문제는 없습니다. 유형 안전을 포기하는 것입니다.

4

void*을 사용할 때 컴파일러가 자신이 가리키는 형식에 대한 가정을 할 수 없다는 점 외에는 성능상의 단점이 없습니다. 그것은 여전히 ​​다른 어떤 포인터와 같습니다.

void*은 객체 유형에 대한 포인터가 void*으로 변환 될 수 있기 때문에 임의의 유형을 가리키는 데 C에서 유용했습니다. 그러나, 그것으로 꽤 많은 것을하는 것은 정의되지 않은 행동을 초래할 것입니다. 원래 포인터 유형으로 안전하게 다시 캐스팅 할 수 있습니다.

그러나 C++에서는 임의의 유형 (템플릿)에 대한 포인터를 저장하는 훨씬 더 좋은 방법이 있습니다. 일부 템플릿 인수 T의 경우 T*을 사용할 수 있습니다.

+1

'정확함'은 정확하지만 유용하지 않을 수 있습니다. 나는'same' 또는'original'이라는 단어를 사용합니다. ** 템플릿 **에 관해서는 –

+0

+5. – Destructor

5

void*의 두 가지 심각한 성능 단점이 있습니다. 첫째는 때를 소프트웨어가 더 어려워 재 작업하게 이후, 그것은 훨씬 더 어려운 이해하고 유지 보수 프로그래머 — 및 런타임에서의 성능에 심각한 영향을 미치는 프로그램을 유지할 수 있다는 것입니다 프로파일 러에 성능 문제가있는 위치가 표시됩니다. 가장 빠른 프로그램은 먼저 프로그램을 다시 작성하지 않고도 중요한 장소 인 에서 로컬 최적화를 수행 할 수 있으므로 처음에 잘 작성된 프로그램입니다 ( ).

두 번째 성능상의 영향은 void*이 의 별칭 일 수 있다는 것입니다. 적절한 앨리어싱 분석은 컴파일러 최적화의 중요한 부분이며,이를 더 잘 수행하기 위해 수행하는 작업은 모두 어렵 기 때문에 옵티 마이저를 방해하고 코드가 느려질 수 있습니다. (char*unsigned char*도 마찬가지입니다.)

+0

+1 성능 문제로 명백한 문제를 재구성합니다. –

0

예 - 일부 성능 단점이있을 수 있습니다. void *을 사용하면 엄격한 앨리어싱 가정에 따라 최적화를 비활성화 할 수 있습니다. 더 void * 변수가 없었다 경우

void fun(void * param1, int & param2) 
{ 
    param2 = 7; // 1 
    // do something with param1, param2 not used 
    param2 += 1; // 2 
} 

는, 컴파일러는 할당 1을 제거하고 2 단지 param2 = 8를 생성 할 수 있습니다. 하지만 fun(&i, i)을 호출하면 param1param2을 가리킬 수 있으므로 지금은 불가능합니다.

More about strict aliasing

+0

아마도 당신은 * param2, param1이 사용되지 않은 것을 의미합니다 * –

+0

아니요. 제가 쓴 것을 의미했습니다. –

관련 문제