Frage

Ich bin auf ein ziemlich komplexes Projekt arbeiten, eine benutzerdefinierte Verschlüsselungsroutine, wenn Sie (nur zum Spaß), und ich haben in diese Frage läuft mein Code-Layout in der Gestaltung.

Ich habe eine Reihe von Funktionen, die ich durch den Index aufrufen können, wollen. Insbesondere muss ich der Lage sein, eine für den Verschlüsselungsprozess zufällig zu nennen, aber dann diese Adresse durch einen bestimmten Index in den Entschlüsselungsprozess.

Ich erwäge eine klassische Funktion Array, aber meine größte Sorge ist, dass eine Funktion Array schwierig sein würde, zu halten und ein wenig hässlich. (Das Ziel ist es, jede Funktion Paar in einer separaten Datei zu erhalten, zu reduzieren mal kompilieren und den Code leichter zu verwalten.) Hat jemand eine elegantere C ++ Lösung als Alternative zu einer Funktion Array? Die Geschwindigkeit ist nicht wirklich ein Problem, ich bin mehr Sorgen um die Wartbarkeit.

-Nicholas

War es hilfreich?

Lösung

Sie schreiben könnten so etwas wie:

class EncryptionFunction
{
public:
    virtual Foo Run(Bar input) = 0;
    virtual ~MyFunction() {}
};

class SomeSpecificEncryptionFunction : public EncryptionFunction
{
    // override the Run function
};

// ...

std::vector<EncryptionFunction*> functions;

// ...

functions[2]->Run(data);

Sie könnten operator() anstelle von Run als Funktionsnamen, wenn Sie es vorziehen.

Andere Tipps

Was ist los mit der Funktion Array?

Sie müssen durch den Index-Funktionen aufzurufen. So müssen sie setzen in eine „Wende durch den Index“ Struktur werden irgendwie . Array ist wahrscheinlich die einfachste Struktur, die diesem Bedarf entspricht.

Beispiel (aus meinem Kopf eingeben, möglicherweise nicht kompilieren):

struct FunctionPair {
   EncodeFunction encode;
   DecodeFunction decode;
};
FunctionPair g_Functions[] = {
   { MyEncode1, MyDecode1 },
   { MySuperEncode, MySuperDecode },
   { MyTurboEncode, MyTurboDecode },
};

Was „hässlich“ oder „schwer zu pflegen“ ist im Ansatz oben?

Ein Objekt mit einem Operator () -Methode definiert eine Menge wie eine Funktion handeln kann aber in der Regel schöner sein zu arbeiten.

Polymorphismus könnte den Trick tun. Sie couldf die Strategie Mustern folgen, jede Strategie unter Berücksichtigung eines Ihrer Funktionen zu implementieren (oder ein Paar von ihnen)

Dann einen Vektor von Strategien erstellen und verwenden diese eine Stelle der Funktionsliste.

Aber ehrlich gesagt, ich weiß nicht, das Problem mit der Funktion Array sehen; Sie können leicht eine typedef erleichtern die Lesbarkeit erstellen. Effectifely, werden Sie mit genau der gleichen Dateistruktur am Ende, wenn die Strategie Muster.

// functiontype.h
typedef bool (*forwardfunction)( double*, double* );

// f1.h
#include "functiontype.h"
bool f1( double*, double* );

// f1.c
#include "functiontype.h"
#include "f1.h"
bool f1( double* p1, double* p2 ) { return false; }


// functioncontainer.c    
#include "functiontype.h"
#include "f1.h"
#include "f2.h"
#include "f3.h"

forwardfunction my_functions[] = { f1, f2, f3 };
  • Die Funktionsdeklaration und Definitionen sind in separaten Dateien - Kompilierung ok ist
  • .
  • Die Funktion Gruppierung ist in einer separaten Datei, eine Abhängigkeit, die auf die Erklärungen nur

Sie können einen Blick auf die Boost.Signals Bibliothek . Ich glaube, dass es die Fähigkeit hat seine Funktionen über einen Index zu nennen.

Versuchen Klasse Loki :: Functor. Weitere Informationen unter CodeProject.com

Sie müssen eine Reihe von Funktionszeigern verwenden. Der einzige Haken ist, dass alle Funktionen im Grunde den gleichen Prototyp haben müssen, nur den Namen der Funktion und übergebene Argument Namen variieren kann. Der Rückgabetyp und Argumenttypen (wie auch die Anzahl der Argumente und Ordnung) müssen identisch sein.

int Proto1( void );
int Proto2( void );
int Proto3( void );

int (*functinPointer[3])( void ) =
{
   Proto1,
   Proto2,
   Proto3
};

Dann können Sie etwas tun:

int iFuncIdx = 0;
int iRetCode = functinPointer[iFuncIdx++]();

Wenn Sie in boost::signals Bibliothek sehen, werden Sie ein Beispiel sehr schön sehen, dass sehr elegant ist:
Sie 4 Funktionen wie Angenommen haben:

void print_sum(float x, float y)
{
  std::cout << "The sum is " << x+y << std::endl;
}

void print_product(float x, float y)
{
  std::cout << "The product is " << x*y << std::endl;
}

void print_difference(float x, float y)
{
  std::cout << "The difference is " << x-y << std::endl;
}

void print_quotient(float x, float y)
{
  std::cout << "The quotient is " << x/y << std::endl;
}

Dann, wenn man sich in einer eleganten Art und Weise versuchen, nennen will:

boost::signal<void (float, float)> sig;

sig.connect(&print_sum);
sig.connect(&print_product);
sig.connect(&print_difference);
sig.connect(&print_quotient);

sig(5, 3);

Und der Ausgang ist:

The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top