728x90
반응형
출처 : 조인시 위키
아마도 여러분은 함수포인터를 사용해봤을 것이다. C에서 제공하는 qsort(3)와 같은 함수도 함수포인터를 사용한다. 다음은 qsort(3)을 이용해서 정렬하는 간단한 프로그램이다.
아마도 여러분은 함수포인터를 사용해봤을 것이다. 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에 다음과 같이 선언되어 있다.
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)(); }
728x90
'기술자료 > C C++' 카테고리의 다른 글
C/C++Pre-processor(전처리기)이 대해 ... (0) | 2009.08.11 |
---|---|
const에 애하여............ (1) | 2009.08.11 |
VISUAL C/C++ PROJECT SETTING (1) | 2009.08.11 |
[賢彬] _STDC_, _P() 의 의미. (1) | 2009.08.11 |
const 에 대해서 알아봅시다.. (1) | 2009.08.07 |
[賢彬][c++]도대체 가상함수는 어디에다 쓰는 것일까?? (1) | 2009.08.07 |
[C++] 연산자 오버로딩 (1) | 2009.08.05 |
[賢彬][C++] ofstream, ifstream에 대해서 (0) | 2009.08.05 |