출처 : http://teamblog.joinc.co.kr/yundream/95
여러분은 함수포인터를 사용해봤을 것이다. C에서 제공하는 qsort(3)와 같은 함수도 함수포인터를 사용한다.
다음은 qsort(3)을 이용해서 정렬하는 간단한 프로그램이다.
비교연산의 종류의 갯수만큼 새로운 qsort함수를 만들어야 될 것이다.
위 코드는 일반적으로 잘 컴파일 되지만, 컴파일러의 특성에 따라서 경고를 발생하거나 컴파일이 안되는
문제가 발생할 수 있다. C 컴파일러에서 컴파일을 한다면 경고를 발생할 것이고,
C++ 컴파일러에서 컴파일 한다면 에러가 발생할 것이다. 이는 이들 두개의 언어가 강타입언어이기 때문이다. C++에서 에러가 발생하는 이유는 일반적으로 C++이 더욱 강하게 타입을 검사하기 때문이다.
여러분은 함수포인터를 사용해봤을 것이다. C에서 제공하는 qsort(3)와 같은 함수도 함수포인터를 사용한다.
다음은 qsort(3)을 이용해서 정렬하는 간단한 프로그램이다.
#include <unistd.h> #include <stdio.h> #include <stdlib.h> int compare(const int *one, const int *two) { if (*one > *two) return -1; else return 1; } int a[3] = { 50, 10, 20 }; int main() { qsort(a, 3, sizeof(a[0]), compare); print("%d\n", a[0]); return 0; }qsort 함수는 인자로, 비교에 사용할 함수의 포인터를 받고 있음을 알 수 있다. 만약 함수포인터를 사용하지 않는다면,
비교연산의 종류의 갯수만큼 새로운 qsort함수를 만들어야 될 것이다.
위 코드는 일반적으로 잘 컴파일 되지만, 컴파일러의 특성에 따라서 경고를 발생하거나 컴파일이 안되는
문제가 발생할 수 있다. C 컴파일러에서 컴파일을 한다면 경고를 발생할 것이고,
C++ 컴파일러에서 컴파일 한다면 에러가 발생할 것이다. 이는 이들 두개의 언어가 강타입언어이기 때문이다. C++에서 에러가 발생하는 이유는 일반적으로 C++이 더욱 강하게 타입을 검사하기 때문이다.
qsort 함수는 stdlib.h에 다음과 같이 선언되어 있다.
그러므로 타입을 명확히 하는 것으로 문제를 해결할 수 있다. 이제 C 컴파일러건 C++ 컴파일러건 간에 경고메시지 하나 없이 깔끔하게 컴파일 될 것이다.
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
그러므로 타입을 명확히 하는 것으로 문제를 해결할 수 있다. 이제 C 컴파일러건 C++ 컴파일러건 간에 경고메시지 하나 없이 깔끔하게 컴파일 될 것이다.
qsort(a, 3, sizeof(a[0]), (int (*(const void *, const void *))compare);
클래스 에서의 함수 포인터 사용
다음은 C 스타일의 함수포인터다.
#include <iostream> using namespace std; void apple(void) { cout << "apple" << endl; }; void berry(void) { cout << "berry" << endl; } int main() { void (*fptr)(void); fptr = apple; fptr(); fptr = berry; fptr(); }
위의 코드를 C++ 스타일로 바꾸어 보았다. 함수포인터를 이용해서 멤버변수에 접근함을 알 수 있다.
호출은 '->*'를 이용하면 된다.
#include <iostream> using namespace std; class fruit { public: void apple() { cout << "apple" << endl; } void berry() { cout << "berry" << endl; } }; int main() { fruit x, *y; void (fruit::*f)(void); y = new fruit; f = &fruit::apple; (x.*f)(); f = &fruit::berry; (y->*f)(); delete y; }C++에서의 멤버포인터를 위한 연산자를 따로 제공하다. '.*'을 사용해서 멤버함수를 포인팅할 수 있다.
호출은 '->*'를 이용하면 된다.
이제 qsort() 함수에 정렬연산을 위해서 멤버함수 포인터를 넘겨보도록 하자.
#include <stdlib.h> #include <iostream> using namespace std; class fruit { public: fruit() { f = &fruit::compare; } int (fruit::*f)(const int*, const int*); int compare(const int *one, const int *two) { return ( (*one == *two) ? 0 : *one > *two ); } } apple; int funcptr(const void* one , const void* two) { return ( (apple.*apple.f)( (const int *)one, (const int *)two ) ); }; int a[3] = { 3, 2, 1 }; int main() { int i; cout << "before "; for( i=0; i < 3; i++ ) cout << a[i] << " "; cout << endl; qsort(a, 3, sizeof(a[0]), funcptr ); cout << "after "; for( i=0; i < 3; i++ ) cout << a[i] << " "; cout << endl; return 0; }
friend와 static 에서의 함수포인터 사용
이제 friend와 static 멤버함수에 접근하는 방법을 알아보자. 다음은 friend 함수에 접근하는 방법이다.
#include <iostream> using namespace std; class fruit { public: void apple() { cout << "apple" << endl; } void berry() { cout << "berry" << endl; } friend void cherry(void (fruit::*func)(), fruit x) { (x.*func)(); } } int main() { fruit x; void (fruit::*f)(void); f = &fruit::apple; (x.*f)(); f = &fruit::berry; cherry(f,x); }
다음은 static 멤버함수에 접근하는 방법이다.
#include <iostream> using namespace std; class fruit { public : void apple() { cout << "apple" << endl; } void berry() { cout << "berry" << endl; } static void cherry(void(fruit::*func)(), fruit x) { (x.*func)(); } }; int main() { fruit x; void (fruit::*f)(void); f= &fruit::apple; (x.*f)(); f = &fruit::berry; x.cherry(f,x); return 0; }
클래스에 임베디드된 함수포인터를 호출하는 예제코드다.
#include <iostream> using namespace std; class fruit { public: void (fruit::*ff)(void); void apple() { cout << "apple" << endl; } void berry() { cout << "berry" << endl; } }; int main() { fruit x; void (fruit::*f)(void); f = &fruit::apple; x.ff = &fruit::berry; (x.*f)(); (x.*x.ff)(); return 0; }
템플릿에서의 함수 포인터 사용
템플릿에서의 사용도 가능하다.
#include <iostream> using namespace std; template<class T> class alpha { T data; public : alpha(T x) {data = x;} T show() {cout << data << endl;} }; int main() { int (alpha<int>::*ifunc)(); float (alpha<float>::*ffunc)(); alpha<int> a(123); alpha<float> b(456.78); ifunc = a<int>::show; ffunc = a<float>::show; (a.*ifunc)(); (b.*ffunc)(); }
'Programing > C/C++/STL' 카테고리의 다른 글
[C++]C++의 메모리 영역 (0) | 2009.08.27 |
---|---|
[C/C++]메모리 영역 구분 (0) | 2009.08.27 |
[C++] explicit 키워드 (0) | 2009.07.14 |
Source Code 수행속도 측정하는 방법 (0) | 2009.06.30 |
OpenMP 라고 아십니까?? (0) | 2009.06.30 |