//출처는 코드누리 강의 내용입니다.
함수 포인터에 멤버 함수를 넣을 경우, 클래스명:: 으로 포인터를
설정해야 함.
왜 그럴까?
멤버 함수에는 this 객체가 인자로 전달되기 때문임.
주의할 부분 240801
: 멤버함수 포인터 대입시 객체를 :: 지정하는 것이 아니라 클래스명을 지정하고 있다.
(반환형)(*pF)() = &참조할 함수
- 반드시 객체가 존재해야 함.
: Point 클래스, set 함수를 만들고, 함수 포인터를 만들어라.
그리고 함수 포인터로 인자 1,2를 넣고, 객체의 멤버 데이터를 출력하라.
가) void foo() 전역 함수 만들고,
void(*pFunc)() = &foo; 넣어라.
나) 멤버 함수를 포인터에 넣어라.
#include <iostream>
using namespace std;
class CPoint
{
private :
int x_;
public :
//static 함수는 클래스의 멤버 변수에 접근할 수 없다.
//내부적으로 this 포인터를 인자로 콜하는 것이 아니기 때문.
static void hello(int _num)
{
//밑의 주석 지우면 오류 발생함.
//x_ = _num;
}
};
class Dialog
{
public :
void Close() {}
static void Open() {}
};
void foo() {}
int main(void)
{
//함수 포인터를 지정할 때
//동일한 반환형, 동일한 매개변수를 사용해서 함수를 지정하게 함.
void(*func)() = &foo;
//하지만 이처럼 클래스 내부를 할 수 없다.
//왜냐하면 객체화를 하지 않았으므로
void(*func2)() = &Dialog::Close;
//=> 여기서 알 수 있는 점 :
//1번 : 일반함수 포인터에 멤버 함수의 주소를 담을 수 없음.
//왜냐하면 멤버함수에는 this가 포함되어 있기 때문임
//2번 : 일반 함수 포인터에 static 멤버함수의 주소를 담을 수 있음.
//클래스 내부더라도 어쨋든 this의 속성으로 접근하지 않기 때문.
void(*func3)() = &Dialog::Open;
//3번 : 멤버의 함수를 설정하는 멤버함수 포인터가 있음.
//멤버 함수 포인터를 사용하는 방법 : .* (p->*f3)()
void(Dialog::*func4)() = &Dialog::Close;
//그렇다면 멤버 함수 포인터를 call 할 수 있음?
func4();
//=> 불가능하다... 왜냐하면 클래스의 멤버함수를 호출하기 위해서는 객체화 즉, this가 필요하기 때문
//그렇다면 어찌할 것인가?
//객체화 해서 호출해야 함.
Dialog d;
d.func4(); //but, 클래스 Dialog 에서는 멤버함수 func4를 찾을 수 없음
//c++에서는 멤버함수 포인터를 call 하기 위해 새로운 문법을 만듬.
d.*func4(); // error : 연산자 우선순위 문제가 있음.
(d.*func4)(); // 이런식으로 사용함.
}
: 주석 반드시 봐야함.
알아야 할 점
콜백 함수를 사용할 때 static 함수로 사용할 경우, 해당 static 내부에서는
클래스의 가상함수와 멤버 들에 접근이 불가능함.
- thread를 만들 경우, this에 접근하기 위해 this를 매개변수로 줌.
강의 참고.
멤버 데이터 포인터
위에서 멤버 함수 포인터를 만든 것처럼 활용하면 됨.
하지만 객체가 안되어 있으므로 주소값을 나타냄.