보이드 포인터는 언제 사용합니까?
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_root
Doesn'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
'programing' 카테고리의 다른 글
Vuejs 응용 프로그램에서 $location.protocol() 및 $location.host() 사용 (0) | 2022.07.17 |
---|---|
Vue 상태 데이터를 데이터베이스에 바인딩하는 '적절한' 방법은 무엇입니까? (0) | 2022.07.17 |
VueJs 템플릿이 아닌 메서드에서 이벤트를 듣는 방법 (0) | 2022.07.17 |
String replace()와 replaceAll()의 차이점 (0) | 2022.07.17 |
$syslog.replace()는 브라우저 쿼리 문자열을 업데이트하지 않습니다. (0) | 2022.07.17 |