
c+이 다른 언어보다 강력한 이유중에 하나는 포인터의 존재이다.
일반적으로 포인터를 선언할때는 어떠 자료형의 주소를 담을지 명시해야 한다.
int main()
{
int b = 123;
int* a = &b;
}
이렇게 말이다.
근데 만약 내가 만든 포인터를 float에도 쓰고 int에도 쓰고 싶다면 어떡할까?
혹은 함수의 주소를 가지고 싶다면 어떡할수 있을까?
그렇게 사용하는 것이 바로 보이드 포인터 (void Pointer)라는 것이다!
보이드 포인터
void* ptr;
선언은 정말 간단하다.
int main()
{
void* ptr;
int a = 1226;
float b = 30;
char c = 's';
ptr = &a;
ptr = &b;
ptr = &c;
}
별다른 과정 없이 이렇게 다른 타입을 받아올수 있다.
받아온 데이터를 사용하고 싶다면 해당 데이터 형으로 형변환을 해줘야 한다.
int main()
{
void* ptr;
int a = 1226;
ptr = &a;
int* b = (int*)ptr;
int c = *b + 10;
cout << c;
}
그래서 보이드 포인터에 어떤 자료형을 저장하고 어떤 자료형으로 형변환할지 정확히 알아야 오류를 방지할 수 있다.
또한 보이드 포인터는 저장된 데이터의 자료형과 크기를 알 수 없으므로 직접적인 역참조 연산을 수행할 수 없다.
그리고 함수또한 주소가 존재하기 때문에 함수를 담을수 있다!
void Debug()
{
cout << "Debug" << endl;
}
int main()
{
void* ptr = Debug;
}
이렇게 말이다!
보이드 포인터에 함수를 담을때 주의해야할게 있는데 바로 함수 시그니처를 맞추는것이다.
지금은 ptr와 Debug의 시그니처가 일치하기 때문에 오류가 나지 않는다.
만약 Debug가 매개변수를 맞는다면 아래와 같이 수정해야 한다.
void Debug(const char* _message)
{
cout << _message << endl;
}
int main()
{
void(*ptr)(const char*) = Debug;
}
이게 처음에는 복잡해 보여도 자꾸보다 보면 익숙해진다.
사용할때도 그냥 함수를 사용하듯이 하면 된다.
int main()
{
void(*ptr)(const char*) = Debug;
ptr("Spring!!");
}
매개변수가 없다면 이렇게 사용하면 된다.
void Debug()
{
cout << "Spring" << endl;
}
int main()
{
void(*ptr)() = Debug;
ptr();
}
자주 사용하면 저렇게 형변환을 계속하는게 귀찮기 때문에 typedef을 이용해 간단하게 바꿀수 있다.
void Debug()
{
cout << "123" << endl;
}
typedef void (*FuncPtr)();
int main()
{
FuncPtr ptr = Debug;
ptr();
}
약간 c#의 델리게이트를 보는거 같다.
보인드 포인터를 공부하니까 c#의 델리게이트나 액션을 구현할수 있는 힌트를 얻은거 같다.
'c++' 카테고리의 다른 글
| 사소한 부분에서 메모리를 아끼는법을 알아보자. (0) | 2025.03.10 |
|---|---|
| 복사 연산자를 만들때 주의해야 할점을 알아보자. (1) | 2025.02.05 |
| 컴파일러가 자동으로 만들어 주는 함수들을 알아보자. (1) | 2025.01.14 |
| Cpp의 컴파일 과정을 알아보자. (5) | 2025.01.12 |
| [winApi 프로젝트]북방 프로젝트 (5) | 2024.12.11 |