함수 포인터 배열 질문입니다.

nayana의 이미지

abc.h 파일

      1 #ifndef ABC_H
      2 #define ABC_H
      3
      4 class abc
      5 {
      6 public :
      7     abc();
      8     ~abc();
      9     void function1( int );
     10     void function2( int );
     11     void function3( int );
     12 };
     13
     14 #endif

abc.cpp

      1 #include <iostream>
      2
      3 using std::endl;
      4 using std::cout;
      5
      6 #include "abc.h"
      7
      8 abc::abc()
      9 {
     10
     11 }
     12
     13 abc::~abc()
     14 {
     15
     16 }
     17
     18 void abc::function1( int a )
     19 {
     20     cout << "nayana1 " << a << endl;
     21 }
     22
     23 void abc::function2( int b )
     24 {
     25     cout << "nayana2 " << b << endl;
     26 }
     27
     28 void abc::function3( int c )
     29 {
     30     cout << "nayana3 " << c << endl;
     31 }

fig.cpp

      1 #include <iostream>
      2
      3 using std::cout;
      4 using std::cin;
      5 using std::endl;
      6
      7 #include "abc.h"
      8
      9 int main ( void )
     10 {
     11     abc nayana;
     12
     13     void ( *f[ 3 ] )( int ) = { nayana.function1, nayana.function2, nayana.function3 };
     14
     15     int choice;
     16
     17     cout << " 0 1 2 만 누를세요?";
     18     cin >> choice;
     19     cin.ignore();
     20
     21     while ( choice >= 0 && choice < 3 )
     22     {
     23         ( *f[ choice ] )( choice );
     24
     25         cout << " 0 1 2 만 누를세요?";
     26         cin >> choice;
     27         cin.ignore();
     28     }
     29
     30     cout << "end" << endl;
     31
     32     return 0;
     33 }

이런식으로 함수 포인터 배열을 구현 하였습니다.
다음과 같은 에러가 떨어집니다.

fig.cpp: In function `int main()':
fig.cpp:13: no matches converting function `function1' to type `void (*)(int)'
abc.h:9: candidates are: void abc::function1(int)

함수로 할때는 함수이름만 배열에 집어 넣으면...잘돼던데..
메소드를 함수포인터 배열에 집어 넣을려면 어떻게 해야하나요?

singlet의 이미지

일반 멤버 함수와 static 멤버 함수의 경우를 구분해야 합니다.

일반 멤버 함수는 일반 함수에 비해 this 포인터 하나를 더 받기 때문에, 일반 함수 포인터에 일반 멤버 함수 포인터를 대입하는 것은 불가능합니다. 반면 static 멤버 함수는 this 포인터를 받지 않기 때문에, 일반 함수 포인터에 static 멤버 함수 포인터를 대입할 수는 있습니다.

제시하신 소스에서는 function1 ~ function3 모두가 this 포인터를 전혀 필요로 하지 않으므로, 이들이 static 멤버 함수이더라도 전혀 지장이 없지요. 즉 수정을 가장 적게 하면서 제대로 컴파일되도록 하는 방법은 abc::function1 ~ abc::function3 의 선언 부분을 다음과 같이 고쳐쓰는 것입니다.

static void function1( int );
static void function2( int );
static void function3( int );

그러나 만일 이들을 static 멤버 함수로 만들 수 없다면, 이 방법을 사용할 수 없으므로 일반 함수 포인터 대신에 멤버 함수 포인터를 사용해야 합니다. 불행히도 멤버 함수 포인터는 일반 함수 포인터에 비해 문법이 조금 더(!) 까다롭습니다. fig.cpp 를 다음과 같이 수정해야 하지요.

// ...
void (abc::*f[3])(int) = { &abc::function1, &abc::function2, &abc::function3 };
// ...
(nayana.*f[choice])(choice);

여유가 되신다면, http://www.function-pointer.org 에서 C/C++ 에서의 일반 함수 포인터, 멤버 함수 포인터 및 함수자 functor 까지 다루고 있으니 한 번 살펴보시는 것도 좋을 듯합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.