Frage

Ich habe einige Objekte bekommen, die Variablen auf unterschiedliche Funktionen verlassen. Um es in verschiedene Wörter zu setzen: Es gibt mehrere Arten von Funktionen, auf die sich die Variablen im Objekt verlassen, aber es sollten mehrere Objekte mit diesen Funktionen geben. Für mehr Freigabe habe ich versucht, ein Beispiel zu geben (was nicht funktioniert).

#include <iostream>

class A
{
  double size;

  A( double (*f)() )
  {
    size = (*f)();
  };
};

double fun1()
{
  return 42.0;
}


int main()
{
  A a = A( &fun1() );

  std::cout << a.size << std::endl;
}

Dies ist natürlich ein minimales Beispiel. Die variable Größe hängt von einer bestimmten Funktion ab, die als Argument an die Klasse übergeben werden sollte. Vorstellen fun1 und fun2 als verschiedene Arten von Zufallszahlengeneratoren.

Ich denke, dass die ideomatische Art und Weise in C ++ eine Klasse wäre, die die Variable hält, und die daraus geerbten Klassen werden durch diese Funktion geändert, die die Objekte unterscheidet (bitte korrigieren Sie mich, wenn ich mich mit dieser Annahme falsch mache). Aber meine Frage ist:

Gibt es eine Möglichkeit, einen Konstruktor höherer Ordnung umzusetzen? Wenn ja, wäre ein Beispiel schön.

PS: Wenn ich einige technische Begriffe falsch verwendet habe, würde ich mich freuen, korrigiert zu werden.

War es hilfreich?

Lösung

Ändern:

A( double (*f)() )
{
    size = f();
};

Und:

A a = A( fun1 );

Als du vorbeifuhr &fun1() Das war, die Funktion aufzurufen und dann die Adresse ihres Ergebniss zu übernehmen. Was Sie eigentlich wollten, war der Funktionszeiger selbst, der in gespeicherten fun1.

Andere Tipps

Dieses Beispiel ist bedeutungslos, da Sie den Funktionszeiger nicht für die spätere Verwendung speichern. Sie können dies einfach zu nur umschreiben

class A
{
    double size;

    A(double sz) {
        size = sz;
    };
};

double fun1()
{
    return 42.0;
}


int main()
{
    A a = A(fun1());
    std::cout << a.size << std::endl;
}

Ich schlage vor, stattdessen eine Vorlage zu schreiben, damit Sie einen Funktionszeiger oder ein Funktionsobjekt übergeben können. Dies ermöglicht es dem Compiler, leichter Optimierungen wie in vielen Fällen zu unterlegen, und ist flexibler. Sie sollten auch keine Klammern verwenden, wenn Sie einen Funktionszeiger erwerben.

#include <iostream>

class A {
public:
    template<typename F>
    explicit A(F&& f) : size(f()) {

    };

    double size;
};

double fun1() {
    return 42.0;
}

int main() {
    A a(&fun1);
    std::cout << a.size << std::endl;
}

Sieht so aus, als ob Sie nur die Funktion selbst übergeben werden müssen. Du hast es fast. Hier ist die richtige Syntax:

typedef double (*functype)();

void foo(functype f) {
    cout << f();
}

double bar() {
    return 2.39;
)

foo(bar); // don't call bar here, just pass it as address.

Sie können auch Foo wie folgt erklären:

void foo(double (*f)());

Funktionen sind keine erstklassigen Objekte in C ++. Die einzige Möglichkeit, einen Verschluss mit einigen Variablen zu erzeugen (z. B. wenn Sie die Funktion tragen oder eine nicht statische Mitgliedsfunktion aufrufen möchten) sind Functors (Objekte mit überladenem Operator () ). Es gibt verschiedene Möglichkeiten, ein solches Objekt zu bekommen:

  1. Definieren Sie es selbst, speichern Sie alle notwendigen Variablen in Feldern und geben Sie sie als Argument der Funktion über.
  2. Verwenden Sie die Lambda -Funktionen von C ++ 11 und std :: Funktion
  3. Verwenden Sie Boost :: Funktion und Boost :: Bind.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top