봐도 봐도 헷갈리는 함수 포인터....
자료구조를 공부하다가 다음과 같은 코드를 보고 대혼란이 왔다.
typedef int (*PriotityComp)(HData d1, HData d2);
typedef struct _heap
{
PriotityComp* comp;
//생략
}Heap;
void HeapInit(Heap* ph, PriotityComp pc)
{
//생략
ph->comp = pc; //????
}
아니 대체..... 라인12가 왜 컴파일이 되는 것인가... 내가 알고 있던 함수 포인터는 무엇이었는가... 난 이렇게 살아왔는데...(?) 상태가 되어버림
분명 comp는 PriotityComp* 형이고 pc는 PriotityComp형인데 왜 이런 연산이 가능한 것이지???
싶어서 별 시도를 다 해 보았다.
예 결론은..... 이 코드가 잘못된 것임ㅇㅇ(윤성우의 열혈 자료구조 363p입니다)
아니나 다를까 홈페이지 들어가 보니까 오탈자라고 나와있더라
다음 코드를 실행해 보면
#include <iostream>
typedef int (*ff)(int a, int b);
int func(int a, int b)
{
return a + b;
}
int main()
{
ff f1;
ff* f2;
std::cout << "함수 포인터의 자료형: " << typeid(f1).name() << "\n";
std::cout << "함수 포인터의 포인터 자료형: " << typeid(f2).name() << "\n";
std::cout << "함수 이름의 자료형: " << typeid(func).name() << "\n";
std::cout << "함수 이름의 주소의 자료형: " << typeid(&func).name() << "\n";
std::cout << "함수 이름(함수의 주소): " << func << "\n" <<"함수 이름의 주소: " << &func << "\n";
f2 = &f1;
f1 = func;
std::cout <<"f1 = func, f1의 값: " << f1 << std::endl;
f1 = &func;
std::cout << "f1 = &func, f1의 값: " << f1 << std::endl;
(*f2) = func;
(*f2) = &func;
//f2 = &func; //컴파일 안됨
//f2 = f1; //컴파일 안됨
}
이와 같은 결과가 나온다.
아무튼 그래서 f2에 f1을 대입하는 것과 같은 연산은 말도 안됨
cpp에선 바로 컴파일 에러 난다.
추가적으로 func와 &func가 같은 주소를 갖는 이유는 아마 여기의 내용과 비슷한 맥락에서일 것 같다.
함수 포인터로 함수를 호출할 때 ff(2)와 (*ff)(2) 모두 허용되는 것과 같은 이유... 아마도
그런데 왜 c언어로 맨 위의 코드를 실행했을 때 컴파일 에러가 안났느냐 하면... c에서는 포인터에 무엇을 대입하든 컴파일 에러를 내지 않기 때문이다.
포인터에 주소값이 아닌 정수값을 대입해도 에러를 내지 않는다.
따라서 컴파일이 잘 됐던 것....
알고나니 맥빠지는 이유였음... 단지 오탈자 하나 때문에 내가 몇 시간동안 이러고 있었는지.......
'Computer > C++' 카테고리의 다른 글
[C++] 예외 처리(1) - 예외 메커니즘과 스택 풀기 (0) | 2022.11.28 |
---|---|
[C++] 템플릿 클래스만 쓰면 링크 에러가 나는 이유가 뭘까 (0) | 2022.11.26 |
[C++] 스마트 포인터 클래스 (0) | 2022.11.20 |
[C++] value categories (0) | 2022.11.17 |
[C++] rvalue 참조와 move semantics (0) | 2022.11.16 |