C++ 클래스 내부에 선언된 함수를 argument로 전달하는방법?

seoleda의 이미지

안녕하세요 ^^

씨에선 함수 포인터를 argument로 전달 하는 기능이 있잖아요. 그런데, 함수포인터를 전달할때, class 내부에 선언된 함수는 어떻게 전달하는지 궁금해서요.
참.. 설명하기 어렵네요. 일단 코드를 보시죠.

include <stdio.h>
class Element{
    public:
    Element();
    int odd;
    int even;
};

Element::Element(){
      static int a=0; even=a*2; odd=a*2+1; a++;
};
class List{
    Element list[10];

    public:
    int test(int a, int b, int(*func_argument)(const Element & e));
    int List::in_class_odd(const Element & e){ return e.odd; }
    int List::in_class_even(const Element & e){ return e.even; }
};

int odd(const Element & e){ return e.odd; };
int even(const Element & e){ return e.even; };

int List::test(int a, int b, int(*func_argument)(const Element & e)){
    int sum=0;
    for (int i=a; i<b; i++){
        sum+=func_argument(list[i]);
        printf("%d ,", func_argument(list[i]));
    }
    printf("sum: %d\n", sum);
};
int main(int argc, char* argv[]){
    List l;
    //l.test(0, 10, List::in_class_odd);
    //l.test(0, 10, List::in_class_even);
    l.test(0, 10, odd);
    l.test(0, 10, even);
};

위 코드에서 test 라는 함수 보이시죠? 거기서 세번째 인자가 함수 잖아요.
그런데 제가 하고 싶은건, 세번째 호출되는 함수가 만일 class 내부에 선언되있으면, main에서 test를 호출할때, 어떤식으로 해야 하느냐는 거죠.

현재로썬 클래스 외부에 그냥.. 단독으로 선언된 함수는 그냥 그 함수명을 써주면 되는데 클래스 내부에 있는 함수는 잘 안되네요. 예를 찾아봐도 클래스 내의 함수를 호출한 경우는 없어서 이렇게 질문 드립니다.

감사합니다. 그럼 이만.. ^^

icanfly의 이미지

#include <stdio.h>
class Element{
    public:
    Element();
    int odd;
    int even;
};

Element::Element()
{
      static int a=0; even=a*2; odd=a*2+1; a++;
};

class List
{
    Element list[10];

    public:
    int test(int a, int b, int(*func_argument)(const Element & e));
    static int in_class_odd(const Element & e){ return e.odd; }
    static int in_class_even(const Element & e){ return e.even; }
};

int odd(const Element & e){ return e.odd; };
int even(const Element & e){ return e.even; };

int List::test(int a, int b, int(*func_argument)(const Element & e))
{
    int sum=0;
    for (int i=a; i<b; i++){
        sum+=func_argument(list[i]);
        printf("%d ,", func_argument(list[i]));
    }
    printf("sum: %d\n", sum);
};

int main(int argc, char* argv[]){
    List l;
    l.test(0, 10, List::in_class_odd);
    l.test(0, 10, List::in_class_even);
    //l.test(0, 10, odd);
    //l.test(0, 10, even);
};

그냥 static 키워드만 추가 했습니다.

결과는 어렇게 나오네요.

1 ,3 ,5 ,7 ,9 ,11 ,13 ,15 ,17 ,19 ,sum: 100
0 ,2 ,4 ,6 ,8 ,10 ,12 ,14 ,16 ,18 ,sum: 90
seoleda의 이미지

static 라는 키워드는 변수에만 사용하는줄 알았는데...

그런데 함수는 월래 static한 영역(?)에 올라가는게 아닌가요? ㅋㅋ
예전에 얼핏본 책에서 클래스에 대해 설명한 부분에, 만일 100개의 class를 선언한다면, 100개의 멤버변수에 대해서는 메모리가 확보 돼지만, 멤버함수는 단 한개의 메모리 공간만 잡혀서 멤버함수는 공유한다고 그림을 본 기억이 있어서요.

C/C++은 알면 알수록 더 신비롭네요. 공부를 더 해야하겠습니다.

단변 진심으로 감사드립니다. ^^

p.s. 이번엔 템플릿 버전으로 작성을.. ㅋㅋ

bugiii의 이미지

멤버함수에 static이 붙는다면 이 함수는 일반 함수와 마찬기지 취급을 받습니다. 다만 사용상 class_name::func_name 이런식으로 스코프를 제한하는 형태로 사용하게 됩니다. 그리고, 이런 함수는 그 클래스의 static이 아닌 멤버에 접근할 수 없습니다.

일반 멤버 함수의 경우 그 함수 코드 자체는 그 클래스의 모든 객체에 동일하지만 멤버 함수가 불려질 때 내부적으로 객체의 주소가 같이 전달되는 형태이고 static 멤버 함수는 그렇지 않습니다.

일반 멤버함수는 그 클래스의 객체 주소와 같이 호출되기 때문에 객체마다 다른 멤버에 접근할 수 있습니다.

만약, 멤버 함수의 포인터나 리퍼런스를 콜백으로 사용하고 싶다면 다른 방법을 찾아야 하는데, 이것은 템플릿을 이용하여 가능하게 할 수 있습니다. (자동으로 템플릿 인자의 타입을 추출해서 최적의 타입을 찾아냅니다.) 더 자세한 내용은 mem_fun, mem_fun_ref 등을 참고하시기 바랍니다.

doldori의 이미지

class List{ 
    Element list[10]; 

public: 
    int test(int a, int b, int(List::*func_argument)(const Element & e)); 
    int List::in_class_odd(const Element & e){ return e.odd; } 
    int List::in_class_even(const Element & e){ return e.even; } 
}; 

int List::test(int a, int b,
               int (List::*func_argument)(const Element & e))
{
    int sum=0;
    for (int i=a; i<b; i++){
        sum+=(this->*func_argument)(list[i]);
        printf("%d ,", (this->*func_argument)(list[i]));
    }
    printf("sum: %d\n", sum);
    return sum;
}

int main(int argc, char* argv[])
{
    List l;
    l.test(0, 10, &List::in_class_odd);
    l.test(0, 10, &List::in_class_even);
}

지금은 List::in_class_odd(), List::in_class_even() 에서 this에 접근하지
않으므로 static으로 선언해도 됩니다만, 클래스의 비정적 멤버에 대한 포인터를
쓴다면 위 코드처럼 할 수 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.