公共变量糟糕的做法与Getters和Setters功能相比?

时间:2015-09-17 08:00:07

标签: c++

我在他的小溪中遇到过这个,从那以后就像一个酸痛的拇指一样向我伸出。我想也许如果我保存视频并在将来回到它时我会更加精通我会理解它,但它只是一直困扰着它。这是视频......

它会自动从1:13:00开始。

https://youtu.be/uHSLHvWFkto?t=4380

作为C / C ++的新程序员,在听到这个之后,它完全扭曲了我的思维方式。由于他是一名专业人士而且我应该接受建议,但我需要一些清晰度。从网站,视频到书籍,我已经读到使用公共变量是一种不好的做法,但是从我从这个视频中得到的结果却是另外说的。在视频中,他使用的结构默认情况下具有“公共”的访问修饰符与默认访问“私有”的类。有没有我在这里无法理解的东西。

我不知道该怎么办。如果我公开我的变量,我不会冒险模糊吗?他说他会自动解雇某人进行格式编码的方式对我来说哈哈!我应该真正使用哪一个?什么时候和为什么?

4 个答案:

答案 0 :(得分:15)

根据我的经验,人们没有充分理由过度使用getter / setter。

可以想到两种主要的类:将相关数据组合在一起的类和其他提供行为的类。

必须封装行为类,不包含公共数据成员。

数据类通常应该将数据成员公开且没有行为。

这两者之间的灰色区域是可变数据类,在成员之间具有不变量或依赖性,例如如果成员a为1,则成员b必须在[1-10]范围内。对于这种情况,使用getter / setter可能是合理的。对于不可变数据类,构造函数必须建立不变量。

答案 1 :(得分:10)

首先,struct完全等同于class,但默认成员访问权限为public而不是private

现在,在面向对象编程(OOP)中,被认为是拥有public数据成员(变量)的好习惯,因为这使 all 成为你的代码依赖于class的内部,从而打破了OOP的原始原则,那就是......

神圣和神圣的封装

封装是一种编码理念,它声明一个类应该使用两个数据和在一个紧密的实体中管理它的代码。也就是说,您不直接访问数据,而是使用class中的方法来操纵此类数据。这有几个设计优势,例如,您将知道除了类中的代码之外,没有代码可能包含有关此类信息操作的错误。

现在,get()set(),也称为访问者完全谎言!有了访问器,当你非常打破时,你会欺骗你自己认为你尊重封装!它增加了膨胀,不必要的冗长,错误,以及除封装外的一切。不要使用class Person unsigned getAge()void setAge(unsigned),而是使用unsigned getAge() a void incrementAge(),或者您想要叫它。

现在,问题的核心......

“普通老式”结构

封装不总是 。虽然你应该(通常)对头文件执行此操作(同样,至少对于某些封装),您可以创建对于单个翻译而言是私有的静态旧struct单元。我的建议是使它们比现在更“老”,即......

  • 所有数据成员均为public
  • 没有方法。
  • 没有构造函数(隐式构造函数除外)。
  • 继承始终是公开的,只允许来自其他普通的旧struct
  • 我再说一遍,不要将它们放在头文件上!

现在,普通旧struct的另一个用途是(具有讽刺意味的)元编程导出constexpr数据和类型,也称为现代 - 硬核 - 模板 - 元编程 - 无需输入 - public - 无处不在,例如......

template<bool B, typename T>
struct EnableIf {};

template<typename T>
struct EnableIf<true, T> {
    typedef T type;
};

template<bool B, typename T>
using SFINAE = typename EnableIf<B, T>::Type;

答案 2 :(得分:5)

如果将数据成员公开,则很难控制对象的内部一致性。

运行良好的是使用构造函数来设置对象的状态,然后使用公共函数来检索成员变量的值,但仅在需要时才使用。如果您需要在构造后改变对象,那么为此提供非常具体的方法。

但是,如果您的对象只是聚合正交数据类型的对象,则对所有成员使用公共访问权限:struct适用于此。

请注意,structclass之间的区别在于前者,默认访问权限为public,而后者则为private var view1 = Backbone.View.extend({ _onEvent : function(){ Backbone.trigger('customEvent'); } }); var view2 = Backbone.View.extend({ initialize : function(){ Backbone.on('customEvent', this._onCustomEvent, this); }, _onCustomEvent : function(){ // react to document edit. } });

答案 3 :(得分:-1)

如果您将数据成员保密,那么您可以轻松控制访问其值。例如,代码中包含age变量。

public:
int age;

现在,班级以外的人可以轻松更改年龄值,也可能会分配非法值,例如age = -10。但是你的逻辑表明年龄不能是负数,所以最好的做法是保持变量私有,并给出一些能为你的变量赋值的函数。

private:
int age;

public:
void setAge(int age)
{
 if (age > 0)
   this->age = age;

}