programing

보이드 포인터는 언제 사용합니까?

javaba 2022. 7. 17. 12:22
반응형

보이드 포인터는 언제 사용합니까?

malloc 구현을 위한 void 포인터의 사용은 이해했습니다.

void* malloc  ( size_t size );

다른 이유를 제시하거나 실제로 도움이 되는 시나리오를 제시할 수 있는 사람은 누구입니까?

고마워요.

void포인터는 데이터 블록의 내용이 중요하지 않을 때마다 사용해야 합니다.예를 들어 데이터를 복사할 때 메모리 영역의 내용은 복사되지만 데이터의 형식은 중요하지 않습니다.

없이 에서는, 「메모리 블록」을 사용해 주세요.void포인터는 사용자가 함수가 데이터 형식을 신경 쓰지 않는다는 것을 알 수 있도록 설계를 명확하게 합니다.의 경우 하여 "A"를 취득합니다.char *기능이 실제로 콘텐츠에 의존하지 않는 경우 메모리 블록을 처리합니다.

의 좋은 시나리오 ' ' ' 'void*ADT를 ADT로 사용합니다.그것은, 어떤 데이터 타입을 보관해, 처리할지를 모르는 경우에 한정됩니다.예를 들어 다음과 같은 링크된 목록입니다.

typedef struct node_t node;
struct
{
    void* data;
    node* prev, next;
} node_t;

typedef struct list_t list;
typedef void* (func)(void*) cpy_func;
typedef void (func)(void*) del_func;
struct
{
   node* head, tail, curr;
   cpy_func copy;
   del_func delete;
} list_t;

initializeLinkedList(cpy_func cpy, del_func del);
//here you keep going defining an API

예를 들어 초기화 함수 포인터를 목록에 복사하여 나중에 해제할 수 있는 다른 함수에 전달합니다. '이렇게'를 void*을 사용하다

생각에는void*C++에서는 템플릿이나 펑터 등 같은 결과를 얻기 위한 보다 안전하고 정교한 방법이 있기 때문에 C++에서는 C++를 프로그래밍할 때 malloc을 사용할 필요가 없습니다.

C++에 대해서는, 특별한 예를 가지고 있지 않습니다.

보이드* 및 기타 C 토픽에 대한 모든 것을 배울 수 있는 좋은 방법은 iTunes-U에서 환상적인 스탠포드 "프로그래밍 패러다임"의 전반부를 보는 것입니다.Void*(C제너릭)와 포인터 전반이 환상적으로 설명됩니다!C를 더 잘 배울 수 있게 도와줬는데...

함수에서 다른 유형의 데이터를 수용하려면 void *를 사용하는 것이 가장 큰 용도 중 하나입니다.(http://syslog.30.syslog/programming/node87.syslog의 예도 남습니다).

다음은 이러한 기능을 사용할 수 있는 추가 예입니다.

  int i;
  char c;
  void *the_data;

  i = 6;
  c = 'a';

  the_data = &i;
  printf("the_data points to the integer value %d\n", *(int*) the_data);

  the_data = &c;
  printf("the_data now points to the character %c\n", *(char*) the_data);

만약 당신이 무료 스탠포드 수업을 보고 싶지 않다면, 나는 보이드 포인터를 검색해서 그곳의 모든 자료를 읽을 것을 추천한다.

void 포인터를 사용하면 큰 이점이 있습니다. 포인터 변수는 다른 변수의 주소를 저장하는 변수입니다.예:

int a;
int *x= &a;

이제 'x'는 정수 변수의 주소를 저장합니다.

하지만 이것은 실패합니다.

float f;
int *x = &f;

정수 포인터 변수는 정수 변수 주소만 저장할 수 있기 때문입니다.다른 데이터 유형에도 동일하게 적용됩니다.

void * 포인터를 사용하면 모든 TYPE 변수의 주소를 저장할 수 있는 에지가 제공됩니다.

void *pointer = &i;
void *pointer = &f;

회수하는 동안엔 제거되어야 합니다.

*((int*)pointer)

따라서 보이드 포인터를 주의 깊게 사용하세요.

이게 도움이 될 거야, 고마워

C++에서 void* 포인터의 가장 설득력 있는 사용 사례는 코드가 이미 사용하고 있는 오브젝트에 임의의 "사용자 데이터"를 저장할 수 있는 옵션을 제공하는 것입니다.

, 여러분이 '수업하다', '수업하다'를 칩시다Car를 사용하여 유용한 작업을 수행하는 소프트웨어에서 사용합니다.Car트렁크.Car되어 있는Car이치노이것은 실제로 자동차 클래스를 사용하는 어플리케이션의 목적에 따라 다릅니다.무효.

class Car
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(void* contentsOfTrunk);
        void* contentsOfTrunk() const;

    private:

        void* m_contentsOfTrunk;
}

그럼 이 Car에는 임의의 를 기존의 .Car: "Discription"을 할 수 Car은 '동행'을 합니다.Car오브젝트, 코드 내 어디에 있든 상관없습니다.

이 경우 void*를 사용하는 방법에는 두 가지가 있습니다.

첫 번째 방법은 트렁크콘텐츠 객체의 유형에 따라 클래스를 템플릿화하는 것입니다.

template <class TrunkContentsType>
class Car
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(TrunkContentsType contentsOfTrunk);
        TrunkContentsType contentsOfTrunk() const;

    private:

        TrunkContentsType m_contentsOfTrunk;
}

이것은 불필요하게 침습적인 것으로 보인다.트렁크 콘텐츠의 유형은 어플리케이션에만 중요합니다.Car 객체로 작동하는 알고리즘과 데이터 구조는 트렁크에 무엇이 있는지 상관하지 않습니다.클래스를 템플릿화함으로써 클래스를 사용하는 응용 프로그램이 트렁크 콘텐츠의 유형을 선택하도록 강제할 수 있지만 대부분의 경우 응용 프로그램도 트렁크 콘텐츠에 신경을 쓰지 않습니다.

두 번째 대안은 트렁크 콘텐츠용 데이터 멤버와 접근자를 추가하는 Car에서 새로운 클래스를 도출하는 것입니다.

class Car
{
    public:

        // Existing methods of your Car class
        // No methods having anything to do with trunk contents.

    private:

        // No data member representing trunk contents.
}

class CarWithTrunkContents
{
    public:

        // Existing methods of your Car class

        void setContentsOfTrunk(TrunkContentsType contentsOfTrunk);
        TrunkContentsType contentsOfTrunk() const;

    private:

        TrunkContentsType m_contentsOfTrunk;
}

★★★★★CarWithTrunkContents입니다.class는 트렁크콘텐츠를 저장합니다.이치노클래스의 동작에 영향을 주지 않는 데이터를 추가하기 위해 완전히 새로운 클래스를 도출해야 하는 이유는 무엇입니까?,, 이, 용, 용을 ,Car트렁크 콘텐츠를 저장하는 클래스입니다.왜 각 어플리케이션이 특정 유형의 트렁크콘텐츠에 대해 새로운 클래스를 강제로 취득할 필요가 있습니까?

마지막으로, 트렁크 콘텐츠에 대한 저의 계획적인 예가 아마도 임의의 트렁크 콘텐츠와 함께 이동하는 생생한 그림을 그릴 수 있습니다.Car오브젝트, 실제로는 어플리케이션 고유의 데이터를 접속하기 위한 보다 일반적인 메커니즘을 제공할 수 있습니다.Car:

class Car
{
    public:

        // Existing methods of your Car class

        void setUserData(void* userData);
        void* userData() const;

    private:

        void* m_userData;
}

이와 같이, 애플리케이션은 트렁크 내용을 나타내는 오브젝트, 운전면허 및 등록을 나타내는 오브젝트, 렌탈 계약을 나타내는 오브젝트 등을 첨부할 수 있습니다.이러한 보이드* 포인터는 "userData"(클래스 사용자가 이해함), "blindData"(클래스가 전송하는 객체의 내용을 인식하지 못함) 또는 "applicationData"(애플리케이션에 의해 정의된 유형 및 목적의 데이터)라고 합니다.

C 코드와 인터페이스하여 C++ 오브젝트를 통과해야 하는데 C 라이브러리가 범용 포인터만 취득하면 포인터를 적절한 타입으로 재캐스팅해야 합니다.

보이드 포인터는 자주 사용해서는 안 되지만, 임의의 포인터로 동작하는 라이브러리 기능을 사용하려고 할 때 도움이 됩니다.또, 그 메모리에 의해서 표시되는 데이터는 별로 신경 쓰지 않습니다.

이는 일반적으로 수치 코드에서 사용됩니다.예를 들어 C 루트솔버 함수는 다음과 같습니다.

double find_root(double x0, double (*f)(double, void*), void* params)
{
/* stuff */
y = f(x, params);
/* other stuff */
}

params에 의해 캐스팅되다f알고 있는 구조에 따라 다르지만, 하지만find_rootDoesn't.

void 포인터는 여러 운영 체제에서 실행해야 하며 기본 프레임워크 API에 상당히 의존하지 않아야 하는 코드를 작성할 때 유용합니다.

예를 들어 OS X, Windows 및 Linux는 모두 윈도 오브젝트의 기본 개념을 가지고 있지만 모두 매우 다릅니다.따라서 이러한 코드를 void*로 전달하고 다음으로 void*를 네이티브 타입(HWND 등)으로 전송하는 플랫폼 고유의 구현에 공통 코드를 사용할 수 있습니다.

하지만, 다른 사람들이 이 분야에서 말했듯이, 이런 종류의 일은 필요한 경우를 제외하고는 확실히 피해야 한다.

void *실제로는 C-ism이며, C가 다른 방법으로는 합리적으로 할 수 없는 일을 할 수 있도록 합니다.

char *플랫폼마다 다른 유형의 포인터를 만들 수 있기 때문에 portable로 사용할 수 없습니다.char *(또는 사이즈가 동일하다고는 할 수 없습니다)void *.

따라서 데이터 유형이 C에서 알려지지 않은 경우(또는 다형성 또는 동적인 경우),void *를 사용하면 올바른 기본 포인터 유형(무엇을 올바르게 가리킬 수 있는 유형)을 생성할 수 있습니다.

C++의 경우void *일반적으로는 레거시 C 코드와 어떤 형태로든 인터페이스 하는 경우를 제외하고는 표시되지 않습니다.

이러한 C "일반"의 또 다른 예는 void *와 함께 구현된 표준 Qsort 함수입니다.

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

int, long, double, char * 또는 일부 구조 포인터의 배열을 정렬할 수 있습니다.

C와 인터페이스 하는 것 외에, 나는 내가 몇몇 코드를 디버깅/추적해야 할 때, 그리고 특정 포인터의 주소를 알고 싶을 때만 보이드 포인터를 사용한다는 것을 알게 된다.

SomeClass * myInstance;
// ...
std::clog << std::hex << static_cast< void* >(myInstance) << std::endl;

다음과 같은 것을 인쇄합니다.

0x42A8C410

그리고 내가 하려는 일을 잘 문서화하고 있다고 생각한다(인스턴스에 관한 것이 아니라 포인터 주소를 알고 있다).

sqlite3_exec()을 확인합니다.SQL 쿼리를 시작하고 결과를 어떤 방식으로(컨테이너에 저장) 처리하려고 합니다.sqlite3_exec()을 호출하여 원하는 오브젝트(컨테이너 포함)에 콜백포인터와 보이드* 포인터를 전달합니다.sqlite3_exec() 실행 시 취득한 각 행의 콜백을 호출하고 void* 포인터를 그 행에 전달하여 콜백이 포인터를 캐스팅하고 원하는 모든 작업을 수행할 수 있도록 합니다.

중요한 것은 sqlite3_exec()은 콜백이 무엇을 하고 어떤 포인터를 전달하는지 상관하지 않는다는 것입니다.void*는 이러한 포인터용입니다.

int (*f) (void);
f =(void*) getprocaddress(dll,"myfunction");

컴파일러를 기쁘게 하다

언급URL : https://stackoverflow.com/questions/1025579/when-to-use-a-void-pointer

반응형