2012-02-19 3 views
0

Я пытаюсь изучить концепцию указателя на функцию. Я написал код, который бросает ошибки, которые я не мог расшифровать. Пожалуйста, посмотритеУказатель на функцию Ошибка во время компиляции

 # include<iostream> 
    # include<stdio.h> 
    # include<conio.h> 

    using namespace std; 
    typedef int(*pt2Func)(int,int); 

    class A 
    { 
      private : int x; 
        int y; 
      public: 
        A(){} 
        A(int a, int b) 
        { 
        x=a; 
        y=b; 
        } 
        int sum(int a, int b){return a+b;} 
        int sub(int a , int b){return a-b;} 
        int mult(int a, int b){return a*b;} 
        pt2Func GetPtr2(const char c) 
        { 
         if (c == '+') 
         return &sum; // line 25 
         else if(c== '-') 
         return &sub; // line 27 
         else if(c=='*') 
         return &mult; //line 29 
        } 
        void pass_ptr(int (*pointer_fn)(int,int)) 
        { 
        int result; 
        result=(*pointer_fn)(10,5); 
        cout << " result is : " << result; 
        } 
        ~A(){} 
    }; 

    int main() 
    { 
     A a(0,5); 
     pt2Func=(a.GetPtr2)('+');   //line 43 
     int result = (a.*pt2Func)(5,10); //line 44 
     cout << "result is " << result; 
     getch(); 
     return 0; 
    } 

На компиляции этой программы, я получаю следующие ошибки в строке 25,27,29:

cannot convert `int (A::*)(int, int)' to `int (*)(int, int)' in return 

Я также получаю ошибку в строке 43 и 44, которые являются

expected primary-expression before='token' 
+1

Подсказка: при работе с указатели функций, создайте свой 'typedef', а затем просто используйте его. –

+1

Объявление моего typedef как typedef int (A :: * pt2Func) (int, int); удаляет несколько ошибок, но я по-прежнему остаюсь с ошибкой, например: -'ISO C++ запрещает принимать адрес неквалифицированной или нестационарной нестатической функции-члена для формирования указателя на функцию-член. Say '& A :: sum'' – Invictus

ответ

2

Вам нужно заменить typedef int(*pt2Func)(int,int); с:

class A;         // <-- forward declaration 
typedef int (A::*pt2Func)(int,int); 

Затем вам нужно заменить return &sum; с return &A::sum; так, чтобы он соответствовал типу, который вы определили.

И вы также должны заменить эти строки:

pt2Func=(a.GetPtr2)('+');   // <-- pt2Func is type, name of variable is missing 
int result = (a.*pt2Func)(5,10); // <-- type name (pt2Func) is not allowed here 

с этим:

pt2Func ptr = a.GetPtr2('+'); 
int result = (a.*ptr)(5, 10); 

Тогда он будет работать, как это было предназначено для работы;)

+0

Спасибо тонну LihO :) – Invictus

1

Указатели-члены-члены - это не то же самое, что указатели на функцию. Я предлагаю прочитать раздел часто задаваемых вопросов по C++, посвященный этой теме: [33] Pointers to member functions.

1

Функция sum() является функцией члена нестатической, и это тип не int (*)(int,int). Это тип int (A::*)(int,int), как показано в сообщении об ошибке компилятора. То же самое относится к двум другим функциям: sub и mult.

Существует два решения. Самое простое решение, чтобы сделать этим функциям static функции члена, то все в вашей программе будет работать без особых изменений, за исключением следующего:

//pt2Func=(a.GetPtr2)('+'); //line 43 - error 
pt2Func=a.GetPtr2('+');  //line 43 - corrected 

//int result = (a.*pt2Func)(5,10); //line 44 - error 
int result = pt2Func(5,10);  //line 44 - corrected 
3

Указатель функции не являются такими же, как pointer to (non-static) member functions.

Есть несколько способов, чтобы исправить вашу программу, я перечислю их:

  • Используйте свободные функции или статический вместо функций членов
  • Изменения типа к указателю на член ((A::*)(int, int))
  • Использование std::function/std::bind
Смежные вопросы