2017-02-08 4 views
1

Ich habe eine Klasse, die ein paar große Felder hat (sagen wir, einige große Matrizen) und verfügt über Elementefunktionen diese Matrizen zu berechnen (die tatsächliche Anzahl der Matrizen ist größer, natürlich)Passing Klasse Feld Memberfunktion

class MyClass { 
protected: 
    MatrixType m_11, m_12; 
public: 
    void compute_m_11(double x); 
    void compute_m_12(double x); 
} 

Jetzt ist der Berechnungscode sehr ähnlich, und der komplexeste Teil ist die korrekte Indexierung der Matrixelemente (die für alle beteiligten Matrizen gleich ist). Also habe ich darüber nachgedacht, die Indizierung und die Berechnung in separate Funktionen aufzuteilen: eine compute_matrix Funktion, die die Indexierung durchführt und eine compute_element Funktion für jeden Satz von Indizes in der Matrix aufruft. Dies würde die Lesbarkeit des Codes erheblich verbessern und das Debuggen erleichtern.

Also würde die compute_matrix Funktion eine MatrixType Referenz auf die Klasse Feld, die ich ausfüllen muss und eine std::function, die die tatsächliche Berechnung durchführen würde nehmen. Ich möchte natürlich vermeiden, irgendetwas zu schreiben, das zusätzliches Kopieren der Matrizen erfordert, da sie ziemlich groß sein können.

Also, die Fragen sind:

  1. Ist es legal/effizient einen Verweis auf eine Klasse Feld auf eine Elementfunktion der Klasse zu übergeben?
  2. Wenn ja, muss ich std::bind verwenden, um die Berechnungselementfunktionen zu übergeben? Die compute_elements Funktionen müssen auf einige andere Felder von MyClass zugreifen.

Dies ist, was ich im Sinn haben:

class MyClass { 
protected: 
    MatrixType m_11, m_12; 
    double compute_elements_m11(int i, int j, double x); 
    double compute_elements_m12(int i, int j, double x); 
    void compute_matrix(MatrixType &m, double x, std::function<double(int, int, double) > f); 
public: 
    void compute_m_11(double x) {compute_matrix(m_11, x, compute_elements_m11);}; 
    void compute_m_12(double x) {compute_matrix(m_12, x, compute_elements_m12);}; 
} 
+0

Wie letzteres "Code-Lesbarkeit und Leichtigkeit (s) debugging verbessert" im Vergleich zu ersterem völlig entkommt mir, aber ich lasse das als eine Frage der Meinung, nehme ich an. Die Rechtmäßigkeitsfrage (1) lässt sich leicht durch einfaches * Versuchen * lösen. Und (2) einmal im Körper von 'compute_elements_xxx' (wie auch immer du kommst,' bind' oder sonstwie), hast du Zugriff auf das Objekt (du bist besser; du bist in einer seiner Mitgliedsfunktionen, 'das' ist bereits eingerichtet), also hättest du besser gesagt - Zugang oder etwas ging schrecklich schief. – WhozCraig

+0

Die Lesbarkeit und das Debugging werden verbessert, da die Matrix auf komplexe Weise durchlaufen werden muss, und die Entkopplung von dieser und der Berechnung ermöglicht es, den Code zu schreiben, der die Matrixelemente nur einmal durchläuft.Und der Berechnungscode selbst ist ziemlich kurz - ohne den Indizierungsteil wird es ziemlich einfach sein, die Korrektheit zu überprüfen. – Kunstmord

Antwort

3

Es ist legal (und nicht ungewöhnlich), einen Mitgliedsverweis zu übergeben, aber Ihr Funktionstyp ist falsch.
könnten Sie verwenden std::bind, oder Sie können einen einfachen Zeiger-to-Mitglied verwenden:

class MyClass { 
protected: 
    MatrixType m_11, m_12; 
    double compute_elements_m11(int i, int j, double x); 
    double compute_elements_m12(int i, int j, double x); 
    void compute_matrix(MatrixType &m, double x, double (MyClass::*f) (int, int, double); 
public: 
    void compute_m_11(double x) {compute_matrix(m_11, x, &MyClass::compute_elements_m11);}; 
    void compute_m_12(double x) {compute_matrix(m_12, x, &MyClass::compute_elements_m12);}; 
}; 

std::bind und std::function obwohl eine flexiblere Implementierung gibt.

+0

Ich denke, Sie meinen 'MyClass ::' nicht 'MatrixType ::' in den Funktionssignaturen – Caleth

+0

@Caleth Natürlich. – molbdnilo

+0

Der lustige Teil ist, wo Sie den Funktionszeiger in Ihrer compute_matrix-Implementierung aufrufen müssen. Da compute_elements_m1 [1/2] nicht statisch ist, müssen Sie auf Ihr aktuelles Objekt zeigen. So z.B. '(this -> * f) (1, 2, x)' – JHBonarius

-1

Warum würden Sie einen Verweis auf ein Klassenfeld zu einer Klasse Member-Funktion übergeben? Eine bessere Lösung wäre, eine Get-Methode zu implementieren und diese in der compute_matrix-Funktion zu verwenden. Ihre Klasse wird dann in etwa so aussehen:

class MyClass { 
protected: 
    MatrixType m_11, m_12; 
    double compute_elements_m11(int i, int j, double x); 
    double compute_elements_m12(int i, int j, double x); 
    void compute_matrix(double x, std::function<double(int, int, double) > f); 
public: 
    void compute_m_11(double x) {compute_matrix(x, compute_elements_m11);}; 
    void compute_m_12(double x) {compute_matrix(x, compute_elements_m12);}; 

    MatrixType& getMatrixType_11(return m_11); 
    MatrixType& getMatrixType_12(return m_12); 

} 
+0

"[...] und verwenden Sie das in der Member-Funktion". In welcher Mitgliedsfunktion meinst du? Es ist 'compute_matrix()', das wissen muss, ob man 'm_11' oder' m_12' lesen soll. Nur einige zusätzliche Hilfsfunktionen hinzuzufügen, wird nicht helfen. –

0

Sicher ist es nicht ungewöhnlich, dass ein Klassenattribut zu einem internen Element Funktion zu übergeben und Sie können auch std:bind verwenden, um die Memberfunktion aufrufen, aber die Frage ist, was Sie wirklich brauchen oder können Sie einfach ein einfaches "if" oder etwas Ähnliches verwenden, um zu entscheiden, was Sie verwenden sollen? Ich würde sagen, es hängt davon ab, wie viele Möglichkeiten Ihr Code-Pfad hat, um das besser zu entscheiden.

Verwandte Themen