C++ C++;:私有结构的每个单个成员的通用getter/setter

C++ C++;:私有结构的每个单个成员的通用getter/setter,c++,struct,private,member,getter-setter,C++,Struct,Private,Member,Getter Setter,可能是一个常见的主题,但在这里找不到任何现有主题 因此,我有一个具有多个成员的私有结构的类。我想为单个成员编写getter和setter,但为每个成员编写一个getter/setter将是一个漫长而重复的过程。。。如何轻松地成为通用 class C { public: typedef struct S { int a, b, c, d, e, f, g, h; }S; void setS(S new_struct);

可能是一个常见的主题,但在这里找不到任何现有主题

因此,我有一个具有多个成员的私有结构的类。我想为单个成员编写getter和setter,但为每个成员编写一个getter/setter将是一个漫长而重复的过程。。。如何轻松地成为通用

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;

}
用什么来代替?????用以直接指代我想要的S元素(a到h)

不用说,我需要这个结构保持为一个结构,不与我的其他类成员混合,并且我还需要能够一次完全获取/设置这个结构

提前感谢,


Charles如果你的动机是积极的,这是一个坏主意,但是为每个成员写一个getter/setter将是一个漫长而重复的过程

对于
C
的用户来说,为每个成员指定明确的名称是很有用的。几乎所有支持OOP的语言都是这样设计的。也许smalltalk是个例外

您还提到必须对setter进行验证。
setElement
功能将很快变得复杂

如果您想保持函数调用的类型安全性,您可以获得更多代码来实现这一点

话虽如此,如果你想要什么建议????可能是,一个简单的枚举就可以了

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

     setSElement(SElement member, int value);

仅使用一个函数设置
S
的特定数据成员 您可以使用以下界面:

void setSElement(int S::*field, int val) {
    data.*field = val;
}
int getSElement(int S::*field) const {
    return data.*field;
}
您可以这样使用它:

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

std::cout
enum
std::array
可以像这样使用

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)];
    }       
};
C类{
公众:
阵列元素;
枚举类索引{a,b,c};
void setElements(const std::array&elems){elems=elems;}
std::数组getElements()常量{return Elems;}
void setElemAtIndex(索引处,int值){
元素[static_cast(at)]=值;
}
int getElemAtIndex(索引处)常量{
返回元素[static_cast(at)];
}       
};
并且可以像这样使用

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);
cobj;
集合元素(std::数组{1,2,3});
auto elems=obj.getElements();
对象setElemAtIndex(C::index::C,30);
自动a=obj.getElemAtIndex(C::index::C);

从您的需求来看,似乎您需要一些枚举:

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)];
}
C类{
公众:
枚举类EIndex{A,B,C,D,E,F,G,H};
结构{
int get(EIndex)常数;
int&get(EIndex);
INTA,b,c,d,e,f,g,h;
};
void集(const S&new_data){data=new_data}
const S&get()const{return data;}
void setSElement(EIndex索引,int值){data.get(index)=value;}
int getSElement(EIndex索引){return data.get(index);}
私人:
S数据;
}
intc::S::get(EIndex索引)常量
{
常量int数组[]={a,b,c,d,e,f,g,h};
返回数组[static_cast(index)];
}
int&C::S::get(EIndex索引)
{
int*array[]={&a,&b,&c,&d,&e,&f,&g,&h};
返回*数组[静态_转换(索引)];
}
用法:

C c;
c.setSElement_a(30);
printf("a = %d\n", c.getSElement_a());

可能不总是这样,但是如果您想要这样的东西,设计中通常会有一些错误。为什么
S
是私有的,如果您为此成员提供getter/setter抛出
C
?为什么不使用数组来代替,因此,您为
.1)为什么私有+获取/设置提供了索引:因为需要在getter/setter中进行大量检查和转换(检查值一致性,从度转换为弧度,检查单位一致性,并在需要时执行其他转换…),但我不想让用户担心2)为什么不使用数组:因为我希望S的成员有明确的名称,它们都有非常不同的含义,而不仅仅是序列中的相似元素
#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)
C c;
c.setSElement_a(30);
printf("a = %d\n", c.getSElement_a());