哪种方法更适合实现get/set?

Ami*_*yan 16 c++ get set

实现get/set有两种方法.

方法1:

单独定义get和set.

class my_class
{
  // ...
};

class main_class
{
public:

  my_class get_data() const
  {
    return m_data;
  }

  void set_data(my_class value)
  {
    m_data = value;
  }

private:

  my_class m_data;
};
Run Code Online (Sandbox Code Playgroud)

注意:在这种方法中,get足够快:http://cpp-next.com/archive/2009/08/want-speed-pass-by-value

另一种方法是(方法2):

定义两个get主体,First const和另一个非const.

class my_class
{
  // ...
};

class main_class
{
public:

  const my_class& get_data() const
  {
    return m_data;
  }

  my_class& get_data() // Works like set.
  {
    return m_data;
  }

private:

  my_class m_data;
};
Run Code Online (Sandbox Code Playgroud)

使用这些方法:

void main()
{
  main_class cls;

  // For method 1.
  my_class data;
  data = cls.get_data();
  cls.set_data(data);

  // For method 2.
  const my_class data1;
  my_class data2;
  data1 = cls.get_data();  // const get invoked.
  cls.get_data() = data2; // Like set beacuase non const get invoked.

}
Run Code Online (Sandbox Code Playgroud)

我的问题这些实现get/set的方法哪个更好?

你知道更好的方法吗?


编辑:对于认为方法1更好的答案,在下面的情况下你怎么说:

void main()
{
  main_class cls;

  // For method 1.
  cls.get_data().do_something_else(); // Not effictive for cls, because data losts.

  // For method 2.
  cls.get_data().do_something_else(); // Effictive for cls.    
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*den 16

您应该始终使用任何自定义类的引用来传递地址而不是值类.您还应该避免传回非const引用进行编辑.请参阅下面的我的建议.

class my_class
{
  // ...
};

class main_class
{
public:

  const my_class & get_data() const
  {
    return m_data;
  }

  void set_data(const my_class & data)
  {
    m_data = data;
  }

private:

  my_class m_data;
};
Run Code Online (Sandbox Code Playgroud)


nat*_*han 11

我知道这对C++纯粹主义者来说并不是一个受欢迎的答案,在我学习Python之前,Ruby我不会提出这种可能性......但是......因为你提供的getter和setter不进行范围检查或特殊计算为什么不让会员公开?

 class main_class
 {
  public:
    my_class my_data;
 }
Run Code Online (Sandbox Code Playgroud)

当然,你会失去const吸气剂并且无法保证保护,但无论如何你都无法保证,因为你提供了一个修改成员的固定功能.

  • +1,整体*real*选项是选项1,带有参数的setter使您能够执行检查,或者只是将成员公开.将成员私有化只是为了编写两个将其转换为public的方法是没有意义的. (9认同)
  • 您忘记了至少为您提供封装的方法,并且将来可能会添加一些检查,或者更改类的内部实现,您不会破坏与用户的API. (3认同)

unk*_*ulu 8

第二个是非常糟糕的,因为它放弃了封装:你也可以将相应的字段公开,任何人都可以在没有你的对象知道它的情况下访问它.您无法根据要更改的数据等执行范围检查或状态更新.