Notice
Recent Posts
Recent Comments
Link
- 책_곽용재님 홈페이지
- 책_노란북 - 책 가격비교
- 책_김재우-SICP번역
- 플밍_쏘쓰포지
- 플밍_CodingHorror ?
- 플밍_상킴
- 플밍_김민장님
- GPGStudy
- 플밍_미친감자님
- 플밍_jz
- 플밍_샤방샤방님
- 플밍_글쓰는프로그래머2
- 플밍_키보드후킹
- 사람_재혁
- 사람_kernel0
- 사람_박PD
- 사람_경석형
- 사람_nemo
- 사람_kikiwaka
- 사람_Junios
- 사람_harry
- 사람_어떤 개발자의 금서목록..
- 사람_모기소리
- 사람_낙타한마리
- 사람_redkuma
- 사람_영원의끝
- 사람_민식형
- 도스박스 다음카페
- 플레이웨어즈 - 게임하드웨어벤치마크
- http://puwazaza.com/
- David harvey의 Reading Marx's c…
- 씨네21
- 한겨레_임경선의 이기적인 상담실
- 본격2차대전만화 - 굽시니스트
- 영화_정성일 글모음 페이지
- 영화_영화속이데올로기파악하기
- 음식_생선회
- 죽력고
- 사람_한밀
- 플밍_수까락
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 책
- 고등학교 사회공부
- 정성일
- 일리아스
- 정신분석
- Programming
- 소비자고발
- modernc++
- 삼국지
- 진중권
- 유머
- 강유원
- 게임
- template
- programming challenges
- c++
- 노무현
- 태그가 아깝다
- 진삼국무쌍5
- 프로그래밍
- BSP
- 삼국지6
- 유시민
- stl
- 고전강의
- 건강
- 영화
- 김두식
- 인문학
- 단상
Archives
- Today
- Total
01-05 01:43
lancelot.com
pointer to member function 본문
- 멤버함수의 호출원리(this call)
class Point
{
public:
int x{ 0 };
int y{0};
public :
void set(int a, int b) { x = a; y = b; }
};
int main()
{
Point pt1;
Point pt2;
pt1.set(10, 20);
pt2.set(10, 20);
}
- 주의
- 실제 함수 인자가 전달되는 방식과 객체 주소가 전달되는 방식은 약간의 차이가 있다.
- 표준으로 정해진 사항은 아니므로 32bit/ 64bit 환경, 컴파일러에 따라서도 차이가 있을 수 있음.
- static member 함수는 객체의 주소가 전달되지 않는다. this call 이 아님.
- 객체의 주소를 알 수 없기때문에 x, y에 접근할 수 없음.
- member function pointer
- 일반 함수 포인터에 "멤버 함수의 주소를 담을 수 없다"
- 일반 함수 포인터에 "static member 함수는 담을 수 있다"
class X
{
public :
void mf1(int a) {} // void mf1(X* this, int a)
static void mf2(int a) {}
};
void foo(int a) {}
int main()
{
void (*f1)(int) = &foo; // ok
// void (*f2)(int) = &X::mf1; // error 일반 함수 포인터에 멤버함수 주소를 담을 수 없다.
void (*f3)(int) = &X::mf2; // ok 일반 함수 포인터에 static 멤버함수는 담을 수 있다.
void(X:: * f2)(int) = &X::mf1; // ok
f1(10); // ok. 일반 함수포인터로 함수 호출.
// f2(10); // error. 객체가 필요하다.
X obj;
// obj.f2(10); // error. f2라는 멤버를 찾게된다
//pointer to member 연산자 사용
// obj.*f2(10); // error 연산자 우선순위 문제
(obj.*f2)(10); // ok
}
- 함수의 주소를 얻는 방법
- foo : ok. 함수 이름은 함수 주소로 암시적 변환 가능
- &foo : ok
- X::mf1 : error. 멤버함수는 반드시 주소연산자(&) 필요
- &X::mf1 : ok
- 멤버함수 포인터를 사용해서 멤버 함수를 호출하는 방법
- f2(10) : error. 멤버함수를 호출하려면 객체가 필요
- obj.f2(10) : error. obj 객체에서 f2라는 멤버가 있는지 검색
- obj.*f2(10) : error. () 연산자가 .* 연산자보다 우선순위가 높다
- (obj.*f2)(10) : ok
- Pointer to Member Operator
- 멤버에 대한 포인터(멤버함수 포인터, 멤버 변수 포인터)를 사용해서 멤버에 접근할 때 사용하는 연산자
- .* : (obj.*f2)(10);
- ->* : (pObj->*f2)(10); pobj는 obj를 가리키는 포인터
- 일반 함수포인터와 멤버함수 포인터
- 함수포인터를 사용해서 함수를 호출하는 방법이 달라서 불편할 경우가 있다.
- STL에는 이것을 도와주는 몇가지 도구가 제공됨.
- std::invoke ( C++17 )
- <functional> header
- 일반 함수포인터와 멤버 함수포인터(정확히는 callable object)를 동일한 방법으로 사용(호출)할 수 있다.
- std::mem_fn ( C++ 11 )
- <functional> header
- 멤버 함수의 주소를 인자로 받아서 함수 주소를 담은 래퍼 객체 반환.
#include<functional>
class X
{
public :
void mf1(int a) {}
};
void foo(int a) {}
int main()
{
X obj;
void (*f1)(int) = &foo;
void(X::*f2)(int) = &X::mf1;
f1(10); // 일반 함수포인터 사용
(obj.*f2)(10); // 멤버 함수포인터 사용
// f2(&obj, 10); // 이렇게 사용가능하면 좋지 않을까?
// uniform call syntax 제안
// 채택 안됨
// std::invoke(C++17)
// -> <funtional> header
// -> 일반 함수포인터와 멤버 함수포인터(정확히는 callable object)를 동일한 방법으로 사용(호출) 할 수 있다.
std::invoke(f1, 10); // f1(10);
std::invoke(f2, obj, 10);
std::invoke(f2, &obj, 10);
// std::mem_fn(C++11)
// -> <funtional> header
// -> 멤버 함수의 주소를 인자로 받아서 함수 주소를 담은 래퍼 객체 반환.
auto f3 = std::mem_fn(&X::mf1);
f3(obj, 10);
f3(&obj, 10);
}