2016-04-20 7 views
3

Wahrscheinlich eine gemeinsame, aber kann kein vorhandenes Thema hier finden.C++: generische Getter/Setter für jedes einzelne Mitglied der privaten Struktur

So habe ich eine Klasse mit einer privaten Struktur mit vielen Mitgliedern. Ich möchte Getter und Setter für einzelne Mitglieder schreiben, aber es wäre lang und repetitiv, einen Getter/Setter für jedes Mitglied zu schreiben ... wie einfach zu sein?

class C { 

    public: 
     typedef struct S { 
      int a, b, c, d, e, f, g, h; 
     }S; 
     void setS(S new_struct); 
     S getS(); 
     void setSElement(????, int value); 
     int getSElement(????); 
    private: 
     S data; 

} 

Was zu ersetzen die ????? mit direkt darauf beziehen, welches Element von S ich will (a bis h)?

Keine Notwendigkeit zu sagen, ich brauche die Struktur, um eine Struktur zu bleiben und nicht mit meinen anderen Klassenmitglieder vermischt werden, und ich muss auch in der Lage sein, die Struktur vollständig auf einmal zu bekommen/setzen.

Vielen Dank im Voraus,

Charles

+2

Vielleicht nicht immer, aber es ist normalerweise etwas falsch im Design, wenn Sie so etwas wollen. – WiSaGaN

+0

Warum 'S' ist privat, wenn Sie Getter/Setter für diese Mitglieder werfen werfen' C'? – Jarod42

+1

Warum verwenden Sie nicht stattdessen ein Array und so stellen Sie den Index für "????" bereit. – Jarod42

Antwort

3

Dies ist eine schlechte Idee, wenn Ihre Motivation ist, aber es würde lange und sich wiederholende sein, einen Getter/Setter für jedes Mitglied zu schreiben ....

Es ist nützlich für den Benutzer von C, explizite Namen für jedes Mitglied zu haben. So werden fast alle Sprachen, die OOP unterstützen, entworfen. Vielleicht ist Smalltalk die Ausnahme.

Sie erwähnen auch, dass Sie die Validierung für die Setter durchführen müssen. Die setSElement Funktion würde schnell komplex werden.

Wenn Sie die Typ-Sicherheit für den Funktionsaufruf beibehalten möchten, erhalten Sie noch mehr Code, um das zu erreichen.

Das gesagt, wenn Sie einen Vorschlag für was ???? könnte sein, eine einfache enum wäre in Ordnung.

class C{ 
    public: 
    enum SElement{ a, b ... 

    setSElement(SElement member, int value); 
1

Um bestimmte Daten Mitglied S mit nur eine Funktion setzen Sie eine solche Schnittstelle verwenden können:

void setSElement(int S::*field, int val) { 
    data.*field = val; 
} 
int getSElement(int S::*field) const { 
    return data.*field; 
} 

und man kann es in einer solchen Art und Weise verwenden:

C c; 
c.setSElement(&C::S::a, 17); 
c.setSElement(&C::S::b, 16); 
std::cout << c.getSElement(&C::S::a) << "\n"; 

durch die Weg in C++ brauchen Sie nicht solche C-Weg-Combo: typedef struct S {} S, können Sie einfach schreiben struct S {}.

1

enum und std::array kann dergleichen verwendet werden,

class C { 
public: 
    std::array<int, 3> Elems; 
    enum class index {a, b, c}; 

    void setElements(const std::array<int, 3>& elems) { Elems = elems;} 
    std::array<int, 3> getElements() const { return Elems;} 

    void setElemAtIndex(index at, int value) { 
     Elems[static_cast<int>(at)] = value; 
    } 
    int getElemAtIndex(index at) const { 
     return Elems[static_cast<int>(at)]; 
    }  
}; 

und dergleichen verwendet werden;

C obj; 
obj.setElements(std::array<int, 3>{1, 2, 3}); 
auto elems = obj.getElements(); 

obj.setElemAtIndex(C::index::c, 30); 
auto a = obj.getElemAtIndex(C::index::c); 
1

Von Ihren Anforderungen entspricht, es scheint, dass Sie etwas Enum wollen:

class C { 
    public: 
     enum class EIndex {A, B, C, D, E, F, G, H}; 
     struct S { 
      int get(EIndex) const; 
      int& get(EIndex); 
      int a, b, c, d, e, f, g, h; 
     }; 
     void setS(const S& new_data) { data = new_data} 
     const S& getS() const { return data; } 
     void setSElement(EIndex index, int value) { data.get(index) = value; } 
     int getSElement(EIndex index) { return data.get(index); } 
    private: 
     S data; 
} 

int C::S::get(EIndex index) const 
{ 
    const int array[] = {a, b, c, d, e, f, g, h}; 
    return array[static_cast<int>(index)]; 
} 

int& C::S::get(EIndex index) 
{ 
    int* array[] = {&a, &b, &c, &d, &e, &f, &g, &h}; 
    return *array[static_cast<int>(index)]; 
} 
0
#include <stdio.h> 
#include <cstddef> 

class C { 
    public: 
    typedef struct S { 
     int a, b, c, d, e, f, g, h; 
    } S; 

    inline void setSElement(std::size_t offset, int value) { 
     *(int*)((C::S*)&data + offset) = value; 
    } 

    inline int getSElement(std::size_t offset) { 
     return *(int*)((C::S*)&data + offset); 
    } 

    private: 
    S data; 
}; 

int main(int argc, char const* argv[]) 
{ 
    C c; 
    c.setSElement(offsetof(C::S, a), 20); 
    printf("a = %d\n", c.getSElement(offsetof(C::S, a))); 

    return 0; 
} 

Stenografie Methoden durch Makros:

#define SET_S(__e__) inline void setSElement_ ## __e__ (int value) { setSElement(offsetof(C::S, __e__), value); } 
#define GET_S(__e__) inline int getSElement_ ## __e__() { getSElement(offsetof(C::S, __e__)); } 

    SET_S(a) 
    GET_S(a) 

Verbrauch:

Verwandte Themen