2017-01-04 2 views
1

Ich habe diesen Code, der einen Funktionszeiger verwendet, um Punkt 3 Funktionen Summe, subtrahieren, mul. es läuft gut. aber jetzt ist das Problem, dass ich Funktionen mit verschiedenen no.of Parametern und verschiedenen Datentypen habe. wie man das umsetzt.Funktionszeiger für verschiedene Funktionen mit verschiedenen Datentypen oder Parameter

int add(int a, int b) 
{ 
    cout<<a+b; 
} 
int subtract(int a, int b) 
{ 
    cout<<a-b; 
} 
int mul(int a, int b) 
{ 
    cout<<a*b; 
} 

int main() 
{ 

    int (*fun_ptr_arr[])(int, int) = {add, subtract, mul}; 
    unsigned int ch, a = 15, b = 10,c=9; 
    ch=2; 
    if (ch > 4) return 0; 

    (*fun_ptr_arr[ch])(a, b); 

    return 0; 
} 
+0

Randbemerkung, sollten Sie prüfen, 'ch> 2', nicht' ch> 4 '(oder besser noch,' ch> sizeof (fun_ptr_arr)/sizeof (* fun_ptr_arr) -1'). –

Antwort

0

Die einfache Antwort ist, dass Sie dies technisch nicht tun können. Sie könnten einige Manipulationen vornehmen, indem Sie ein Array als Eingabe für all diese Funktionen verwenden, aber Sie müssen immer noch genau wissen, was Sie an die einzelnen Funktionen weitergeben müssen. Von einer Software-Engineering-Perspektive, sollten Sie dies nicht tun - ich schlage vor, Sie an den schönen Antworten mal hier vorbeischauen: C++ Function pointers with unknown number of arguments

0

Wenn Sie die folgenden Funktionen

int f1(int i); 
int f2(int i, int j); 

haben, können Sie eine generische Funktionstyp definieren wie diese

typedef int (*generic_fp)(void); 

Und dann Ihre Funktion Array initialisieren

generic_fp func_arr[2] = { 
    (generic_fp) f1, 
    (generic_fp) f2 
}; 

Aber Sie werden die Funktionen zurück

int result_f1 = ((f1) func_arr[0]) (2); 
int result_f2 = ((f2) func_arr[1]) (1, 2); 

Offensichtlich zu werfen haben, ist es wie ein guter Weg sieht nicht ein Programm

Um Code ein wenig besser aussehen bauen Sie Makros definieren

#define F1(f, p1) ((f1)(f))(p1) 
#define F2(f, p1, p2) ((f2)(f))(p1, p2) 

int result_f1 = F1(func_arr[0], 2); 
int result_f2 = F2(func_arr[1], 1, 2); 

EDIT

vergessen zu erwähnen, müssen Sie auch einen Typ für jeden definieren Art der Funktion

typedef int (*fi)(int); // type for function of one int param 
typedef int (*fii)(int, int); // type for function of two int params 

Und gieße dann gespeichert Zeiger auf diese Typen

int result_f1 = ((fi) func_arr[0]) (2); 
int result_f2 = ((fii) func_arr[1]) (1, 2); 

hier ein komplettes Beispiel

#include <iostream> 

typedef int (*generic_fp)(void); 
typedef int (*fi)(int); // type for function of one int param 
typedef int (*fii)(int, int); // type for function of two int params 

#define F1(f, p1) ((fi)(f))(p1) 
#define F2(f, p1, p2) ((fii)(f))(p1, p2) 

int f1(int i); 
int f2(int i, int j); 

int main() 
{ 

    generic_fp func_arr[2] = { 
     (generic_fp) f1, 
     (generic_fp) f2 
    }; 

    int result_f1_no_macro = ((fi) func_arr[0]) (2); 
    int result_f2_no_macro = ((fii) func_arr[1]) (1, 2); 


    int result_f1_macro = F1(func_arr[0], 2); 
    int result_f2_macro = F2(func_arr[1], 1, 2); 

    std::cout << result_f1_no_macro << ", " << result_f2_no_macro << std::endl; 
    std::cout << result_f1_macro << ", " << result_f2_macro << std::endl; 

    return 0; 
} 

int f1(int i) 
{ 
    return i * 2; 
} 

int f2(int i, int j) 
{ 
    return i + j; 
} 

Der obige Code wird die folgende Ausgabe

4, 3 
4, 3 
produziert
+0

Fehler treten in dieser Zeile int result_f1 = ((f1) func_arr [0]) (2); int result_f2 = ((f2) func_arr [1]) (1, 2); –

0

Ein bisschen anders Verwenden Sie keine Objekte, um das erforderliche Verhalten zu implementieren. Um eine wirklich generische Art von Lösung zu haben, müssen wir Interfaces verwenden. Die Daten und den Betrieb zerlegen, d. H. Getrennt aufbewahren.

//Interface which describes any kind of data. 
struct IData 
{ 
     virtual ~IData() 
     { 
     } 
}; 

//Interface which desribes any kind of operation 
struct IOperation 
{ 
     //actual operation which will be performed 
     virtual IData* Execute(IData *_pData) = 0; 

     virtual ~IOperation() 
     { 
     } 
}; 

Nun weiß jeder Betrieb die Art der Daten daran arbeiten und nur diese Art von Daten erwarten.

struct Operation_Add : public IOperation 
{ 
      //data for operation addition. 
      struct Data : public IData 
      { 
        int a; 
        int b; 
        int result; 
      }; 

      IData* Execute(IData *_pData) 
      { 
        //expected data is "Operation_Add::Data_Add" 
        Operation_Add::Data *pData = dynamic_cast<Operation_Add::Data*>(_pData); 
        if(pData == NULL) 
        { 
          return NULL; 
        } 

        pData->result = pData->a + pData->b; 
        return pData; 
      } 
}; 

struct Operation_Avg : public IOperation 
{ 
      //data for operation average of numbers. 
      struct Data : public IData 
      { 
        int a[5]; 
        int total_numbers; 
        float result; 
      }; 

      IData* Execute(IData *_pData) 
      { 
        //expected data is "Operation_Avg::Data_Avg" 
        Operation_Avg::Data *pData = dynamic_cast<Operation_Avg::Data*>(_pData); 
        if(pData == NULL) 
        { 
          return NULL; 
        } 

        pData->result = 0.0f; 
        for(int i = 0; i < pData->total_numbers; ++i) 
        { 
          pData->result += pData->a[i]; 
        } 
        pData->result /= pData->total_numbers; 
        return pData; 
      } 
}; 

Hier ist der Betriebsprozessor, die CPU.

struct CPU 
{ 
      enum OPERATION 
      { 
        ADDITION = 0, 
        AVERAGE 
      }; 

      Operation_Add m_stAdditionOperation; 
      Operation_Avg m_stAverageOperation; 
      map<CPU::OPERATION, IOperation*> Operation; 

      CPU() 
      { 
        Operation[CPU::ADDITION] = &m_stAdditionOperation; 
        Operation[CPU::AVERAGE] = &m_stAverageOperation; 
      } 
}; 

Probe:

CPU g_oCPU; 

    Operation_Add::Data stAdditionData; 
    stAdditionData.a = 10; 
    stAdditionData.b = 20; 

    Operation_Avg::Data stAverageData; 
    stAverageData.total_numbers = 5; 
    for(int i = 0; i < stAverageData.total_numbers; ++i) 
    { 
      stAverageData.a[i] = i*10; 
    } 

    Operation_Add::Data *pResultAdd = dynamic_cast<Operation_Add::Data*>(g_oCPU.Operation[CPU::ADDITION]->Execute(&stAdditionData)); 
    if(pResultAdd != NULL) 
    { 
      printf("add = %d\n", pResultAdd->result); 
    } 

    Operation_Avg::Data *pResultAvg = dynamic_cast<Operation_Avg::Data*>(g_oCPU.Operation[CPU::AVERAGE]->Execute(&stAverageData)); 
    if(pResultAvg != NULL) 
    { 
      printf("avg = %f\n", pResultAvg->result); 
    } 
Verwandte Themen