私人设置/获取功能 - 为何私有和如何使用?

时间:2011-08-24 01:30:22

标签: c++ access-modifiers

我已经阅读了很多指南,解释了为什么我应该使用“私人”,答案总是“因为我们不希望其他任何人将此视为某种东西”。那么,让我问下列问题:

假设我想拥有一次设置的变量(可能是视频游戏中的字符名称,请问一次,然后设置,然后你只需使用get变量(编辑:函数)游戏的其余部分)我该如何处理那一套?我如何处理这个问题呢?

在这种情况下使用私有访问修饰符的实际优势是什么?如果我从不提示用户再次输入名称,并且永远不会将信息存储回class.name,那么数据是否应保持安全(适度,假设代码按预期工作)?

我希望有人能帮助我解决这个问题,因为我在Google搜索并在此处看到的解释并没有让我的想法得到休息。

谢谢!

6 个答案:

答案 0 :(得分:2)

访问说明符主要用于表示类接口,而不是有效地限制程序员的访问或保护事物。它们用于防止意外黑客攻击。

如果设置了一次,那么您应该在创建时设置它,并将其设为const

如果界面不需要特别清楚(例如,如果很少有人需要学习它)那么花费精力去设计它是没有意义的。此外,可以在以后应用对界面如何使用没有太大影响的更改。可以使用简单的搜索和替换将暴露的变量更改为getter / setter。

如果它是已发布的二进制接口,那么您希望第一次就能正确使用它。但你只是在谈论你的计划的内部。

任何人都不太可能意外重置玩家名称。

答案 1 :(得分:0)

这是最后一个重要的括号:假设代码按预期工作。

在我看来,它与Linux系统中的权限类似。您知道root密码并且可以删除任何文件,但是您不能以root身份登录,因此您不会意外地执行任何操作。类似地,当你有一个私有变量characterNameString,而某人(或你)稍后试图给它一个新值时,它将失败。那个人必须去查看代码并看到它被标记为私有。那个人将不得不问自己“为什么这是私人的?我应该修改它吗?我应该这样做吗?”如果他们决定他们想要,那么,他们可以。但它可以防止愚蠢的错误。

答案 2 :(得分:0)

我不会试图证明私有集方法的合理性,因为这对我来说听起来有些奇怪。您可以使用朋友声明来处理一组。但是,当朋友可以直接设置值时,为什么要定义一个setter?

如果我可以管理它,我通常会避免使用setter。相反,我更喜欢提供通过构造函数设置成员变量的工具。如果它们有意义,我很乐意提供吸气剂。

class player_character_t {
    std::string name_;
public:
    player_character_t(std::string const& name)
    :   name_ (name)
    {
    }

    std::string const& name() const { return name_; }
};

这会强制您延迟构造对象,直到获得所需的所有信息。它简化了对象的逻辑(即它们有一个简单的状态图),这意味着你在读取它之前就不必检查是否已设置(如果对象存在,则设置正确)。

http://en.wikipedia.org/wiki/State_diagram

将物品标记为私人物品有助于预防事故。因此,当您犯了一个错误并且不再是“代码按预期工作”的情况时,编译器可能会帮助您检测它。同样,const可以帮助您检测何时错误地使用对象。

答案 3 :(得分:0)

请勿混淆该类的私有公开接口。从理论上讲,这些是完全不同的接口,这只是C ++的一个设计特性,它们实际上位于相同的类声明中。

当对象属性应该通过公共接口公开时,拥有公共getter / setter是完全可以的,因此没有诸如“setter始终是私有的”的规则。

Herb Sutter撰写的(更多)例外C ++书籍中有关该主题的更多内容。对于想要理解C ++并精通C ++的人来说,这是一个绝对必要的阅读。

如果您对决定是否在类变量上使用getter / setter有疑问,那么互联网上有很多解释为什么getter / setter更好。

答案 4 :(得分:0)

如果变量是“一次写入然后永远只读”,我建议将其设置为在构造期间初始化的const成员。私有'setter'函数没有任何价值,因为它不会被使用。此外,您还可以避免使用setter函数设置名称,因为它永远不会被设置。

例如:

class Player
{
  private:
    const std::string m_name;

  public:
    Player(const std::string& name) : m_name(name) {}
 };

答案 5 :(得分:0)

当有问题的数据涉及多个变量时,私有的getter和setter都是有意义的,你想要确保遵守的附加约束,以及这些操作在你的类中多次完成。或者,当您计划对数据模型进行进一步修改并希望抽象数据操作时,例如使用std :: vector但计划使其成为std :: map或类似情况。

对于个人示例,我有一个带有私有重置(T *,int *)方法的智能指针实现,该方法本质上是存储对象及其引用计数的setter。它处理检查对象和引用计数的有效性,递增和递减引用计数,以及删除对象和引用计数。它在类中被调用了八次,因此将它放入方法中是完全合理的,而不是每次只使用成员变量,减慢编程速度,膨胀代码并在此过程中冒错误。

我确信如果你从模型中抽象数据和/或你必须实现错误检查,私有的getter也是有意义的,例如,如果数据是NULL而不是返回NULL,则抛出指令。