我应该使用公共或私人变量吗?

Mar*_*čko 31 c++ oop abstraction data-access getter-setter

我是第一次做大项目.我有很多类,其中一些有公共变量,一些有setter和getter方法的私有变量,同样有两种类型.

我决定重写此代码,主要只使用一种类型.但我不知道应该使用哪个(仅用于同一对象中的方法的变量始终是私有的,并且不受此问题的影响).

我知道公共和私人意味着什么,但在现实世界中使用什么以及为什么?

Luc*_*ore 33

private 数据成员通常被认为是好的,因为它们提供封装.

为它们提供getter和setter打破了封装,但它仍然比public数据成员更好,因为只有一次访问该数据的访问点.

你会在调试过程中注意到这一点.如果它是私有的,您知道您只能修改类中的变量.如果它是公开的,您将必须在整个代码库中搜索它可能被修改的位置.

尽可能禁止getter/setter并制作属性private.这遵循信息隐藏的原则 - 您不应该关心类具有什么属性.它应该是独立的.当然,在实践中这是不可行的,如果是这样的话,那么遵循这一设计的设计将比没有设计的设计更加混乱和难以维护.

这当然是一个经验法则 - 例如,我只是使用一个struct(class与公共访问相当),例如,一个简单的点类:

struct Point2D
{
   double x;
   double y;
};
Run Code Online (Sandbox Code Playgroud)

  • 为"尽可能禁止吸气者/安装者"+1.我总是声称制定者是邪恶的(我的意思是功能.我不介意狗). (3认同)

Bal*_*arq 16

既然你说你知道这个理论,而其他答案已经挖掘了公共/私有,getter和setter的含义,我想集中讨论使用访问器而不是创建公共属性的原因(C++中的成员数据) .

想象一下,你在后勤项目中有一个类卡车:

class Truck {
public:
    double capacity;

    // lots of more things...
};
Run Code Online (Sandbox Code Playgroud)

如果您是北美人,您可能会使用加仑来代表卡车的容量.想象一下,您的项目已经完成,它可以完美地工作,尽管Truck::capacity已经完成了许多直接使用.实际上,您的项目取得了成功,因此一些欧洲公司要求您调整您的项目; 不幸的是,该项目现在应该使用公制,因此应该使用升而不是加仑的容量.

现在,这可能是一团糟.当然,一种可能性是仅为北美准备代码库,而仅为欧洲准备代码库.但这意味着错误修复应该应用于两个不同的代码源,并且这决定是不可行的.

解决方案是在项目中创建配置可能性.用户应该能够设置加仑或升,而不是固定的,硬连线的加仑选择.

通过上面所述的方法,这将意味着很多工作,您将不得不追踪所有用途Truck::capacity,并决定如何处理它们.这可能意味着修改整个代码库中的文件.作为替代方案,我们假设您决定采用更多theoretic方法.

class Truck {
public:
    double getCapacity() const
        { return capacity; }

    // lots of more things...
private:
    double capacity;
};
Run Code Online (Sandbox Code Playgroud)

可能的替代更改不涉及对类的接口的修改:

class Truck {
public:
    double getCapacity() const
        { if ( Configuration::Measure == Gallons ) {
            return capacity;
          } else {
             return ( capacity * 3.78 );
          }
        }


    // lots of more things...
private:
    double capacity;
};
Run Code Online (Sandbox Code Playgroud)

(请注意,有很多方法可以做到这一点,只有一种可能,这只是一个例子)

您必须创建全局实用程序类配置(但无论如何必须这样做),并添加一个include in truck.hfor configuration.h,但这些都是本地更改,其余的代码库保持不变,从而避免潜在的错误.

最后,你还说你现在正在一个大项目中工作,我认为这是一个实际上更有意义的领域.请记住,在大型项目中工作时要记住的目标是创建可维护的代码,即可以使用新功能进行更正和扩展的代码.你可以忘记个人小项目中的getter和setter,尽管我会让自己习惯他们.

希望这可以帮助.

  • 我知道这是一个玩具的例子,我大多赞同这些结论,但是,如果你正在运行一个包含多个单元的项目,请不要这样做**.相反,在内部使用SI单位存储所有内容,并且仅在与用户交互时在单元之间进行转换(如果您正在远程执行某些操作,则在视图层中进行转换). (2认同)

HAL*_*HAL 5

什么应该是私人/公共或受保护的,没有硬性规则.

这取决于您班级的作用及其提供的内容.

  • 构成班级内部运作的所有方法和成员都应该是私有的.
  • 课堂向外界提供的一切都应该是公开的.
  • 可能必须在此类的特化中扩展的成员和方法可以声明为受保护的.


sth*_*sth 5

从 OOP 的角度来看,getter/setter 有助于封装,因此应该始终使用。当您调用 getter/setter 时,类可以在幕后做任何它想做的事情,并且类的内部不会暴露于外部。

另一方面,从 C++ 的角度来看,当您只想获取/设置一个值时,如果类做了很多意想不到的事情,这也可能是一个缺点。人们想知道某些访问是否会导致巨大的开销,或者是否简单高效。当你访问一个公共变量时,你确切地知道你得到了什么,当你使用 getter/setter 时,你不知道。

特别是如果您只做一个小项目,那么当您决定更改变量名称/类型/...时,花时间编写 getter/setter 并相应地调整它们,会产生大量的忙碌工作,却收效甚微。您最好花时间编写一些有用的代码。

当 C++ 代码不能提供真正的增益时,通常不会使用 getter/setter。如果您设计一个 1,000,000 行的项目,其中包含许多必须尽可能独立的模块,那么这可能是有意义的,但对于您日常编写的大多数正常大小的代码来说,它们就太过分了。