C ++应该所有成员变量都使用访问器和mutator

时间:2011-03-10 08:59:48

标签: c++ oop

我有大约15~20个成员变量需要访问,我很想知道 如果只是让他们公开而不是给他们每一个人都是好事 获取/设置功能。<​​/ p>

代码就像

class A { // a singleton class
public:
    static A* get();

    B x, y, z;
    // ... a lot of other object that should only have one copy
    // and doesn't change often

private:
    A();
    virtual ~A();
    static A* a;
};

我还考虑过将变量放入数组中,但事实并非如此 知道查找表的最佳方法,将它们放在数组中会更好吗?

编辑:

是否有比Singleton类更好的方法将它们放入集合

6 个答案:

答案 0 :(得分:4)

C ++世界并没有像“一些OO支持的语言”那样,“一切都必须隐藏在访问者/变异者/他们决定称之为今天的东西”之后。

话虽如此,鉴于您的描述有限,有点难以说明最佳方法是什么。

如果你的类只是一个其他进程的“数据包”,那么使用结构而不是类(唯一的区别是所有成员默认为public)都是合适的。

但是,如果类实际执行某些操作,您可能会发现通过函数/方面或接口将get / set例程组合在一起更合适。

正如我所提到的,没有更多信息就很难分辨。

编辑:单例类本身并不是有臭味的代码,但你需要对它们有点小心。如果单例正在处理偏好数据或类似的东西,那么只为每个数据元素创建单独的访问器是有意义的。

另一方面,如果您将通用输入数据存储在单例中,则可能需要重新考虑设计。

答案 1 :(得分:2)

您可以将它们放在POD结构中,并提供对该类型对象的访问:

struct VariablesHolder
{
  int a;
  float b;
  char c[20];
};


class A
{
  public: 
    A() : vh()
    {
    }

    VariablesHolder& Access()
    {
      return vh;
    }
    const VariablesHolder& Get() const
    {
      return vh;
    }

  private:
    VariablesHolder vh;
};

答案 2 :(得分:2)

不,这不会是好事。您想要更改将来访问它们的方式的图像。例如,删除一个成员变量,让get / set函数计算其值。

答案 3 :(得分:2)

这实际上取决于你想要访问它们的原因,更改它们的可能性,使用它们的代码数量,重写或重新编译代码的问题,访问需要多快,是否需要/想要virtual访问,在使用代码等方面更方便和直观。想要访问这么多东西可能是设计不佳的标志,或者它可能是100%合适的。使用get / set函数可以为大量客户端应用程序可以使用的易失性(不稳定/可能经常调整)低级代码带来更多潜在好处。

鉴于您的编辑,如果您的客户端可能想要访问循环中的值,或者数字索引具有固有意义,则数组是有意义的。例如,如果它们是按时间顺序排序的数据样本,则索引听起来不错。总而言之,数组可以更容易地提供算法来处理任何或所有索引 - 您必须考虑这对您的客户是否有用;如果没有,请尽量避免它,因为它可能会更容易错误地访问错误的值,特别是如果说两个人分支一些代码,最后添加一个额外的值,然后尝试合并他们的更改。有时提供名为access的数组,或者为索引提供有意义名称的枚举。

答案 4 :(得分:1)

这是一个可怕的设计选择,因为它允许任何组件修改任何这些变量。此外,由于直接访问这些变量,您无法对值强加任何不变量,如果突然您决定多线程化您的程序,您将不会有一组需要互斥保护的函数,但你必须离开,找到每个数据成员的每一次使用,并单独锁定这些用法。一般来说,应该:

  1. 不使用单身人士或全球变量;它们在组件之间引入了微妙的隐式依赖关系,允许看似独立的组件相互干扰。
  2. 尽可能使变量变为常量,并仅在绝对需要的地方提供setter。
  3. 永远不要公开变量(除非您正在创建POD结构,即使这样,最好只将POD结构创建为内部实现细节,而不是在API中公开它们。)
  4. 另外,您提到需要使用数组。您可以使用vector<B>vector<B*>创建动态大小的B类型对象或B *类型的对象。而不是使用A::getA()来访问您的单例实例;如果函数需要A类型来获取类型为const A&的参数,那会更好。这将使依赖项显式化,并且还将限制哪些函数可以修改该类的成员(将A*A&传递给需要对其进行变异的函数)。

答案 5 :(得分:0)

作为惯例,如果你想要一个数据结构来保存几个公共字段(普通旧数据),我建议使用一个结构(并与其他类一起使用 - builder,flyweight,memento和其他设计模式) )。

类通常意味着您正在定义封装数据类型,因此OOP规则是隐藏数据成员。

在效率方面,现代编译器优化了对访问者/变更者的调用,因此对性能的影响将不存在。

就可扩展性而言,方法绝对是一种胜利,因为派生类可以覆盖这些(如果是虚拟的)。另一个好处是,如果通过成员函数访问数据,则可以添加检查/观察/通知数据的逻辑。

基类中的公共成员通常很难跟踪。