2016-12-19 6 views
1

Ich habe eine Containerklasse, die verschiedene Objekte in einer Karte enthält, die ähnliche Getter-Funktionen haben. Das ist selbst in einer Klasse enthalten, die diese Daten verwendet. also habe ich hier eine kleine Kette, die nicht ideal erscheint.C++ übergeben Funktion selbst als Argument

class Obj { 
    double getA() { return m_a; } 
    double getB() { return m_b; } 
    .... 

    double m_a, m_b, ...; 
} 

class Container { 
    map<long, Obj> m_objs; 

    getA(int i) { return m_objs[i].getA(); } 
    getB(int i) { return m_objs[i].getB(); } 
} 

class User { 
    Conainer m_cont; 
    getA(int i) { return m_cont.getA(i); } 

Gibt es eine allgemeinere Möglichkeit, die Werte der Objekte zu erhalten, indem die aufrufende Funktion irgendwie in sie übergeben wird. Ich gebe zu, dass das ganze Konstrukt mit der langen Kette nicht ideal erscheint, aber in diesem Kontext erscheint es natürlich, weil ich eine Art Baum von Objekten habe und Informationen nach oben zum obersten Knoten transportiere, und ich würde nicht wissen, wie ich das vermeiden kann. Aber wenn es irgendwelche Vorschläge für eine bessere Art und Weise sind damit zu umgehen, ich bin glücklich, es zu hören

+4

Der bessere Weg, damit umzugehen, ist, dass der Container eine einzige 'get()' hat, die das 'Obj &' zurückgibt und der Aufrufer herausfinden kann, welchen Getter er auf das zurückgegebene Objekt aufrufen möchte. –

+0

Das scheint ein ziemlich guter Anfang zu sein. Danke Sam – chrise

+0

Ich denke, dass Sie das Entwurfsmuster verwenden konnten: Fabrikmuster. Dies kann dem Benutzer Ihrer Klasse helfen, Konstruktoren mit langen Ketten zu vermeiden. – Yves

Antwort

2

Das Objekt, das Sie brauchen würde in diesem Szenario passieren wird ein Zeiger auf Elementfunktion:

class Obj { 
    // ... 

    double getA() { 
    return a; 
    } 

    double getB() { 
    return b; 
    } 

private: 
    double a; 
    double b; 
}; 

class Container { 
    // ... 
    get(int i, double (Obj::*what)()) { return (m_objs[i].*what)(); } 
}; 

class User { 
    Container m_cont; 
    // ... 
    get(int i, double (Obj::*what)()) { return m_cont.get(i, what); } 
}; 

// ... 
double myA = user.get(1, &Obj::getA); 

Sie können dies auch zu Obj hinzufügen:

double get(double (Obj::*what)()) { 
    return (this->*what)(); 
} 

Container mehr im Einklang mit User zu machen:

class Container { 
    // ... 
    get(int i, double (Obj::*what)()) { return m_objs[i].get(what); } 
}; 
+0

vielen Dank für das Beispiel – chrise

Verwandte Themen