Avatar billede mesterhakkeren Nybegynder
09. juni 2005 - 22:20 Der er 9 kommentarer og
1 løsning

pointer funktions struktur

jeg har altså nolge forskellige funktioner, med forskelligt altid inputs, og forskellige return værdiger... men nej, om jeg kunne finde ud af at lave en structur til at gemme en reference til funktionerne i, som man kunne styrre med pricippet linked list..

hvordan gør man sig sådan en struktur ??
Avatar billede bertelbrander Novice
09. juni 2005 - 22:54 #1
Det er muligt, men jeg ville nok overveje en ekstra gang om det virkelig er den bedste løsning.

Man kunne foresille sig:

#include <iostream>
#include <vector>

class FuncClass
{
public:
  FuncClass(int (*aFunc)(int, int))
  {
      Func.IntInt_Int_Func = aFunc;
      FuncType = IntInt_Int;
  }
  FuncClass(double (*aFunc)(double, double, double))
  {
      Func.DoubleDoubleDouble_Double_Func = aFunc;
      FuncType = DoubleDoubleDouble_Double;
  }
  enum FuncTypeEnum
  {
      IntInt_Int,
      DoubleDoubleDouble_Double
  };
  FuncTypeEnum FuncType;
  union
  {
      int (*IntInt_Int_Func)(int, int);
      double (*DoubleDoubleDouble_Double_Func)(double, double, double);
  }Func;

  void Do()
  {
      if(FuncType == IntInt_Int)
        std::cout << Func.IntInt_Int_Func(2, 40) << std::endl;
      else
        std::cout << Func.DoubleDoubleDouble_Double_Func(2.2, 40.11, 20.99) << std::endl;
  }
};

int F1(int a, int b)
{
  return a + b;
}

double F2(double a, double b, double c)
{
  return a*b/c;
}

int main()
{
  std::vector<FuncClass > MyVector;
  MyVector.push_back(FuncClass(F1));
  MyVector.push_back(FuncClass(F2));
  size_t i;

  for(i = 0; i < MyVector.size(); i++)
      MyVector[i].Do();
}

Et af problemerne er der hvor man skal kalde funktionen, hvor skal den få sine argumenter fra?
Avatar billede ksoren Nybegynder
09. juni 2005 - 22:58 #2
typedef void (*defFunc0)(); // generisk funktion
typedef int (*defFunc1)(char a);
typedef bool (*defFunc2)(int b);

int func1(char a){
    return (int)a;
}

bool func2(int b){
    return b==b;
}

struct{
    defFunc0 pNext; // generisk funktion
}list[] = {
    (defFunc0)func1, (defFunc0)func2
};


antag [0] peger på en funktion af typen defFunc1:

((defFunc1)list[0].pNext)('a');


så med denne metode, er strukturen nødt til at indeholde en variabel til at identificere funktionstype
Avatar billede mesterhakkeren Nybegynder
09. juni 2005 - 23:01 #3
i dit eks, er det så ikke rigtigt, at der er statiske funktioner til de externe F1 og F2 ??

kan det ikke lade sig gøre at lave noget som holder styr på return værdier, input, og funktions kald, hvis man godtager reglen at alt er en streng ?
Avatar billede mesterhakkeren Nybegynder
09. juni 2005 - 23:02 #4
ksoren >> wow.. skal lige gnaske mig igennem
Avatar billede mesterhakkeren Nybegynder
09. juni 2005 - 23:04 #5
med denne typedef void (*defFunc0)(); kan man angive f.eks

int fnc1(int a, int c);

og

char *fnc2(char *a, int f, bool t);
Avatar billede bertelbrander Novice
09. juni 2005 - 23:21 #6
Man kan naturligvis lade Do() konvertere parametrene fra en streng og returværdien til en streng.

Men det vil være ret ineffektivt.
Avatar billede bertelbrander Novice
09. juni 2005 - 23:28 #7
Det kunne se sådan ud:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

bool Split(std::string &aDest, std::string &aSrc, char aDelim)
{
  if(aSrc.empty())
      return false;
  std::string::size_type pos = aSrc.find(aDelim);
  aDest = aSrc.substr(0, pos);
  if(pos != std::string::npos)
    aSrc = aSrc.substr(pos + 1);
  else
    aSrc = "";
  return true;
}

template <typename T>
bool FromString(T &aValue, const std::string &aStr)
{
  std::stringstream ss(aStr);
  return ss >> aValue;
}

template <typename T>
std::string ToString(T aValue)
{
  std::stringstream ss;
  ss << aValue;
  return ss.str();
}

class FuncClass
{
public:
  FuncClass(int (*aFunc)(int, int))
  {
      Func.IntInt_Int_Func = aFunc;
      FuncType = IntInt_Int;
  }
  FuncClass(double (*aFunc)(double, double, double))
  {
      Func.DoubleDoubleDouble_Double_Func = aFunc;
      FuncType = DoubleDoubleDouble_Double;
  }
  enum FuncTypeEnum
  {
      IntInt_Int,
      DoubleDoubleDouble_Double
  };
  FuncTypeEnum FuncType;
  union
  {
      int (*IntInt_Int_Func)(int, int);
      double (*DoubleDoubleDouble_Double_Func)(double, double, double);
  }Func;

  std::string Do(std::string In)
  {
      if(FuncType == IntInt_Int)
      {
        int a, b;
        std::string T;
        Split(T, In, ',');
        FromString(a, T);
        Split(T, In, ',');
        FromString(b, T);
        a = Func.IntInt_Int_Func(a, b);
        T = ToString(a);
        return T;
      }
      else
      {
        double a, b, c;
        std::string T;
        Split(T, In, ',');
        FromString(a, T);
        Split(T, In, ',');
        FromString(b, T);
        Split(T, In, ',');
        FromString(c, T);
        a = Func.DoubleDoubleDouble_Double_Func(a, b, c);
        T = ToString(a);
        return T;
      }
  }
};

int F1(int a, int b)
{
  return a + b;
}

double F2(double a, double b, double c)
{
  return a*b/c;
}

int main()
{
  std::vector<FuncClass > MyVector;
  MyVector.push_back(FuncClass(F1));
  MyVector.push_back(FuncClass(F2));

  std::string Res;
  Res = MyVector[0].Do("2,40");
  std::cout << "Res1: " << Res << std::endl;
  Res = MyVector[1].Do("2.2,40.11,20.99");
  std::cout << "Res1: " << Res << std::endl;
}
Avatar billede bertelbrander Novice
09. juni 2005 - 23:28 #8
Jeg forstår ikke:
"i dit eks, er det så ikke rigtigt, at der er statiske funktioner til de externe F1 og F2 ??"
Avatar billede mesterhakkeren Nybegynder
02. oktober 2005 - 00:51 #9
NOlge som vil have points ?
Avatar billede mesterhakkeren Nybegynder
05. oktober 2005 - 22:58 #10
lukker så :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester