2016-04-18 8 views
0

Ich habe eine Klasse, in der ich eine Funktion brauche, die ich pro Objekt definieren kann. Ich möchte in der Lage sein, die spezifische Funktion jedes Objekts zu definieren, während ich einen Vektor dieser Objekte definiere. Diese Vektoren meines Objekts werden Teil einer Bibliothek sein. Hier ist ein erfolgloser Beispiel dafür, was ich zu tun versucht:Definieren von Memberfuntion beim Konstruieren eines Objekts

#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; 
} 

So sind die beiden Dinge, die ich bin zu kämpfen, um herauszufinden, oder viel Dokumentation über, sind wie folgt:

  • Wie die Funktion zu definieren, während die Elemente gorgers []
  • definiert, wie die Funktion, die ich an den Konstruktor als (* Func), und speichern sie es als virtuelle Doppel func()

bestanden haben, akzeptieren, Ich würde es vorziehen, die Funktion innerhalb der Objektdefinition definieren zu können. Ich habe ziemlich viel Zeit damit verbracht, herauszufinden, wie ich meinen Vektor von Objekten am besten schreiben kann, und die Art und Weise, wie in dieser Situation am einfachsten zu arbeiten ist, scheint jeden Aspekt eines jeden Objekts in einem Block zu definieren, während der Vektor sie sind in enthalten.

Ich gebe zu, ich weiß auch nicht, ob (* Func) ist richtig, während Sie eine virtuelle Funktion verwenden, aber das ist eine Anpassung von meinem ersten Versuch mit Funktionszeiger. Gerne nehme ich auch alternative Vorschläge an, die besser funktionieren als die Methode, die ich verwenden möchte.

Vielen Dank im Voraus für jede Hilfe, die Sie anbieten können, und ich bin glücklich, meine Frage zu bearbeiten oder zu aktualisieren, wenn nötig.

Pete

+1

'std :: funktion '? Überprüfen Sie die Beispiele hier: http://en.cppreference.com/w/cpp/utility/functional/function –

+0

Von Ihrem Beispiel benötigen Sie keine Funktion, nur doppelte konstante Variable. – Jarod42

+0

@ Jarod42 wo brauche ich nur eine const doppelte Variable? –

Antwort

2

Was Sie wollen, ist eine bessere funktionelle Eigenschaften von Sprache zu unterstützen. Zum Glück benutzen Sie C++!

Nach C++ 11 haben wir lambdas und std::function Objekte, die Laufzeit polymorphe Funktion Objekte darstellen.

ist ein Lambda wie folgt definiert:

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

Ich war faul und verwenden Auto da, aber eigentlich könnten wir es zu einem std::function Objekt zuordnen:

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

Der std::function<double()> Mittel , die Funktion nimmt kein Argument und gibt ein Double zurück. Beachten Sie jedoch, dass der Typ des Lambda kein std::function Objekt ist, aber es ist nicht der Ort, um darüber zu diskutieren.

So können Sie ein std::function<double()> in Ihrer FunctionEater Klasse speichern:

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 
}; 

Dann Ihr Vektor wird dies:

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; 
     } 
    } 
}; 

Und Ihre main?Es ist eigentlich das gleiche:

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

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

Vielen Dank! Ich werde diese beiden Antworten am Morgen versuchen: D –

+0

Ich habe diese Antwort und @ M.Ms Antwort verglichen. Sie sind beide großartige Lösungen und sehr ähnlich, also bin ich mir nicht sicher, was ich als richtig markieren soll. Der einzige wirkliche Unterschied zwischen diesen, den ich sehen kann, ist die Klasse/Struct-Definition für FunctionEater. Ich habe Funktoren, lambdas und std :: function aufgefrischt, damit ich versuchen kann, meinen Kopf dazu zu bringen, aber was würdest du sagen, sind die Hauptunterschiede zwischen diesen zu sehr ähnlichen Ansätzen? –

1

Die richtige Syntax lautet:

#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; 
} 

Sie entweder Definition von Func verwenden können. Der Funktionszeiger hat weniger Overhead, kann aber nur mit einem Capture-losen Lambda arbeiten. Die std::function ist viel flexibler.

NB. Ich bin nicht sicher, warum die Vektorinitialisierung ohne einen Vorlagenkonstruktor für FunctionEater nicht funktioniert, aber ich fand, dass in diesem Fall die Vektorinitialisierer explizit konvertiert werden mussten (entweder zu Func oder FunctionEater).

+0

vielen Dank! Ich werde diese beiden Antworten am Morgen versuchen: D –