C ++:私有结构

时间:2016-04-20 08:53:14

标签: 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);
       S getS();
       void setSElement(????, int value);
       int  getSElement(????);
    private:
       S data;

}

更换什么?????用来直接引用我想要的哪个元素(a到h)?

不用说,我需要结构体保持结构,而不是与我的其他类成员混合,我还需要能够一次性完成/设置结构。

提前致谢,

查尔斯

5 个答案:

答案 0 :(得分:3)

如果你的动机是,这是一个坏主意,但为每个成员写一个getter / setter会很长而且重复......

C的用户对每个成员都有明确的名称很有用。这就是几乎所有支持OOP的语言都是如此设计的。也许smalltalk是例外。

您还提到您必须对setter进行验证。 setSElement函数很快就会变得复杂。

如果你想保持函数调用的类型安全性你可以获得更多代码来实现它。

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

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

     setSElement(SElement member, int value);

答案 1 :(得分:2)

#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;
}

通过宏的简写方法:

#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());

答案 2 :(得分:1)

使用一个函数设置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 way组合:typedef struct S {} S,你可以写struct S {}

答案 3 :(得分:1)

enumstd::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 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);

答案 4 :(得分:1)

根据您的要求,您似乎想要一些枚举:

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)];
}