2016-04-18 2 views
0

J'ai une classe dans laquelle j'ai besoin d'une fonction que je peux définir par objet. Je souhaite pouvoir définir la fonction spécifique de chaque objet en définissant un vecteur desdits objets. Ces vecteurs de mon objet vont constituer une partie d'une bibliothèque. Voici un exemple réussi de ce que je suis en train de faire:Définition d'un membre lors de la construction d'un objet

#include <iostream> 
#include <vector> 

class FunctionEater { 

public: 

    virtual double func() {} 

    FunctionEater(double (*Func)) { 

     func = Func; // Not sure of the correct syntax here 
    } 
}; 

std::vector<FunctionEater> gorgers { 

    { 
     double() { // Not sure of the syntax here, or if there is even syntax to do this 

      double result = 0.794 * 739.775; 
      return result; 
     } 
    }, 

    { 
     double() { 

      double temp1 = 0.794 * 739.775; 
      double result = temp1 + 0.62; 
      return result; 
     } 
    } 
} 

int main() 
{ 
    double snackCrumbs = gorgers[0].func(); 
    double gorgePoop = gorgers[1].func(); 

    std::cout << snackCrumbs << std::endl << gorgePoop << std::endl; 
} 

Ainsi, les deux choses que j'ai du mal à comprendre, ou trouver beaucoup de documentation sur, sont les suivants:

  • Comment pour définir la fonction tout en définissant les éléments de Avaleurs []
  • Comment accepter la fonction que je l'ai passé au constructeur (* Func), et stocker comme deux fonc virtuel()

Je préférerais pouvoir définir la fonction dans la définition de l'objet. J'ai passé pas mal de temps à travailler sur la meilleure façon d'écrire mon vecteur d'objets, et la façon la plus facile de travailler visuellement dans cette situation semble être de définir chaque aspect de chaque objet dans un même bloc, tout en définissant le Je les reconnais, je ne sais pas si (* Func) est correct en utilisant une fonction virtuelle, mais c'est une adaptation de ma première tentative en utilisant des pointeurs de fonction. Je suis également heureux d'accepter d'autres suggestions qui pourraient fonctionner mieux que la méthode que j'essaie d'utiliser.

Merci d'avance pour toute assistance que vous pouvez offrir, et je suis heureux de modifier ou mettre à jour ma question si nécessaire.

Pete

+1

'std :: fonction '? Vérifiez les échantillons ici: http://en.cppreference.com/w/cpp/utility/functional/function –

+0

De votre échantillon, vous n'avez pas besoin de fonction, juste double variable constante. – Jarod42

+0

@ Jarod42 où ai-je juste besoin d'une variable double const? –

Répondre

2

Ce que vous voulez est mieux fonctionnalités prennent en charge de votre langue. Heureusement, vous utilisez C++! Après C++ 11, nous avons des objets lambdas et std::function qui représentent des objets de fonction polymorphes d'exécution.

Un lambda est défini comme ceci:

auto yourSecondFunc = [](){ 
     double temp1 = 0.794 * 739.775; 
     double result = temp1 + 0.62; 
     return result; 
}; 

Je suis paresseux et utilisé il y a auto, mais en fait, nous pourrions l'affecter à un objet std::function:

std::function<double()> yourSecondFunc = [](){ 
     double temp1 = 0.794 * 739.775; 
     double result = temp1 + 0.62; 
     return result; 
}; 

Que std::function<double()> moyen , la fonction ne prend aucun argument et renvoie un double. Notez cependant que le type de lambda n'est pas un objet std::function mais ce n'est pas l'endroit pour en discuter.

Ainsi, vous pouvez stocker un std::function<double()> dans votre FunctionEater classe:

class FunctionEater { 

public: 

    std::function<double()> func; 

    FunctionEater(const std::function<double()>& f) { 

     func = f; 
    } 

    void callMe() { double res = func(); } // how a function object is used 
}; 

Ensuite, votre vecteur devient ceci:

std::vector<FunctionEater> gorgers { 
    FunctionEater { []() 
     { 
     double result = 0.794 * 739.775; 
     return result; 
     } 
    }, 
    FunctionEater { []() 
     { 
     double temp1 = 0.794 * 739.775; 
     double result = temp1 + 0.62; 
     return result; 
     } 
    } 
}; 

Et votre main?Il est en fait le même:

int main() 
{ 
    double snackCrumbs = gorgers[0].func(); 
    double gorgePoop = gorgers[1].func(); 

    std::cout << snackCrumbs << std::endl << gorgePoop << std::endl; 
} 
+0

merci beaucoup! Je vais essayer ces deux réponses dans la matinée: D –

+0

J'ai comparé cette réponse, et la réponse @ M.M. Ils sont tous les deux d'excellentes solutions, et très similaires, donc je ne suis pas sûr de savoir ce qu'il faut corriger. La seule différence réelle entre ceux que je peux voir est la définition de classe/struct pour FunctionEater. J'ai étudié les foncteurs, lambdas et std :: function pour que je puisse essayer de bien comprendre, mais que diriez-vous, selon vous, des principales différences entre ces approches trop similaires? –

1

La syntaxe est:

#include <iostream> 
#include <vector> 
#include <functional> 

struct FunctionEater 
{ 
    using Func = double (*)(); 
    //using Func = std::function<double()>; 

    template<typename F> 
    FunctionEater(F f): func(f) {} 

    Func func; 
}; 

std::vector<FunctionEater> const gorgers = { 
    []{ return 0.794 * 739.775; }, 
    []{ return 0.794 * 739.775 + 0.62; } 
}; 

int main() 
{ 
    double snackCrumbs = gorgers[0].func(); 
    double gorgePoop = gorgers[1].func(); 

    std::cout << snackCrumbs << std::endl << gorgePoop << std::endl; 
} 

Vous pouvez utiliser la définition de Func. Le pointeur de fonction a moins de surcharge mais il ne peut fonctionner qu'avec un lambda sans capture. Le std::function est beaucoup plus flexible.

NB. Je ne suis pas sûr pourquoi l'initialisation de vecteur ne fonctionne pas sans un constructeur de modèle pour FunctionEater, mais j'ai trouvé que dans ce cas les initialiseurs de vecteur devaient être explicitement convertis (Func ou FunctionEater).

+0

merci beaucoup! Je vais essayer ces deux réponses dans la matinée: D –