繁体   English   中英

C ++私有静态成员变量与自由非成员的比较

[英]c++ private static member variables compared to free nonmember


我是C ++的新手,对私有静态成员或“免费非成员”有疑问。

我可以这样写我的代码:

// MyClass.h - Version 1
class MyClass
{
public:
    MyClass();
    ~MyClass();
private:
    static int iValue;
};

// MyClass.cpp
int MyClass::iValue = 123;

另一种没有私有成员的方式,在cpp内部进行内部链接

// Version 2 - static 
static int iValue = 123;

// or anonymouse namespace
namespace
{
    int iValue2 = 123;
}

我可以看到的唯一区别是,即使我无法使用它,也可以从班级外部获得“可见性”。
如果要在外部或派生类中使用iValue,我将在版本1中将静态成员声明为public或受保护的类,或者在该类之上被完全全局声明。 关键字const对我来说还不清楚。

class MyClass
{
private:
    static const int iValue;
// (...)
}

我总是希望尽可能多地从外面隐藏东西。

简而言之:我为什么有理由偏爱版本1而不是版本2?

亲切的问候
尼西

封装是面向对象编程的主要范例之一,因此,如果您的静态成员仅由类本身使用(例如,计算类对象的数量),则应使用版本1(私有静态成员)。 当然,如果您希望派生类能够使用它,则应该将其设置为protected

如果该变量未特别绑定到任何类,则应使用版本2/3(静态全局变量),并且可以在不同的地方使用该版本。 但是,有人可能会认为需要全局变量的代码设计不当,而使用全局变量被认为是一种不好的风格。

如果您需要特定于特定类的恒定值(例如,汽车的车轮数),则可以使用私有静态const成员。

MyClass(类而不是实例)是否具有iValue

是=>使其成为静态成员。

否=>做其他事情。

您想知道该怎么做,这表明您现在没有明显的权衡取舍。 这是一个很好的指示,您可以并且应该做正确的事©,这可以使其他人尽可能简单地理解您的代码,这又意味着:着重于代码的语义。

做正确的事情的人的另一点是:关注点分离,您的班级应该只做一件事情,一件事情。 如果iValue在班级中没有任何关系,但您可能希望将它放在某个班级中的某个地方:请勿随意进行。

这个领域的设计决策需要权衡一些事情,这很容易理解,因此每次需要这种选择时,您都可以权衡利弊:

  • 匿名名称空间或静态非成员允许翻译单元中的所有更高版本代码完全访问。

    • 用于实现文件(例如“ .cc” /“。cpp”)中,它们使您拥有一些静态数据/功能-在对象的符号表中不是extern的-无法通过其他转换单元的代码进行访问。

      • 较小的符号表有时可以减少程序链接和/或加载时间。

      • 通常认为这比私有成员变量具有更少的封装 ,因为一个以上类的代码和朋友可以访问/更改数据(但是类成员的定义可能分布在许多翻译单元中,并且私有数据更容易受到攻击。某些类型的“黑客入侵”访问,例如客户端提供的模板专业化-从未如此简单。

        • 如果希望翻译单元中的更多代码可以访问,则较少的封装是可取的:您正在寻找一种“适合”实际需求的方法。
      • 这减少了(重新)编译依赖性(在Lakosian术语中也称为“物理依赖性”),这意味着您可以在不编辑标题的情况下更改数据/功能,并且仅翻译单元的重新编译就可以链接新的数据/行为以进行合并。但是,有许多客户端对象/可执行文件; 与此相反,对头文件的编辑往往需要重新编译重新链接所有要合并的客户端代码。 在企业级开发中,这对于低级库的更改可能是一个大问题。

    • 在标头中很少使用它们,因为每个包含这样标头的翻译单元都会获得数据/函数的独立“副本”,而且程序很少需要每个翻译单元存储状态的情况非常少; 通常无法清晰地映射到程序数据中具有逻辑意义的分区(例如,运行时每个线程,每个“用户”),并且即使可以对程序进行结构化以使其看起来很有用,通常最好使用以下方法管理多个数据副本:对象实例,使其与翻译单元分离,从而为以后的源代码重构/重构保留灵活性。

    • 他们无法访问任何类的私有/受保护成员,并且建议他们可能与任何特定的类无关,并且可能可重用,这取决于真实性如何,可以帮助或挫败开发人员在分析数据使用情况时的理解或功能行为/实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM