当不需要创建多个对象时,是不是应该将类的成员变为静态?

Posted

技术标签:

【中文标题】当不需要创建多个对象时,是不是应该将类的成员变为静态?【英文标题】:Should members of a class be turned static when more than one object creation is not needed?当不需要创建多个对象时,是否应该将类的成员变为静态? 【发布时间】:2012-12-06 08:56:38 【问题描述】:
class AA

    public:
        AA ();
        static void a1          ();
        static std :: string b1 ();
        static std :: string c1 (unsigned short x);
;

我的班级不会有不同的对象相互之间或与其他对象进行交互。 当然我需要至少有一个对象才能调用这个类的函数,所以我想到了将成员设为static,这样就可以避免不必要的对象创建。

这种设计的优缺点是什么?什么是更好的设计?

【问题讨论】:

为什么还要费心上课呢? 在你的情况下,我认为枚举会更合适。 @Pubby 那么,在哪些情况下我们“需要”上课? @AnishaKaul 当你想创建多个实例时。 @AnishaKaul 大多数使用“singleton”的情况是您想要延迟初始化或私有状态。 【参考方案1】:

要访问静态成员,你甚至不需要对象,只需调用

AA::a1()

这种模式称为“Monostate”,替代方案是单例模式,您可以在其中实际创建一个对象,但请确保它只创建一次,有大量关于如何做到这一点的教程,只需 google 一下。

【讨论】:

如果您在程序生命周期中的任何时候都最多有一个对象,那么您正在谈论单例,并且将其全部设为静态是另一种选择。如果这个数字要超过 1,那么两者都不是一个好的选择 @AnishaKaul 静态成员不会阻止对象创建。为此,您需要私有构造函数或纯抽象类。【参考方案2】:

当不需要创建多个对象时,是否应该将类的成员转为static

当您的类的所有对象只需要一个成员实例时,您就可以创建类static 的成员。当您声明一个类成员static 时,该成员变为每个类而不是每个对象。

当你说你只需要你的类的一个对象时,你可能指的是单例设计模式。请注意,模式被广泛认为是一种反模式,其有用性是否取决于特定情况。

您在Q中提到的原因与您是否应该成为会员static无关。

【讨论】:

@AnishaKaul static 不是单例设计模式,但也可以。 “当你说你只需要你的类的一个对象时,你可能指的是单例设计模式。”这是我错过的一个好点。 单例是一种反模式的原因正是因为它与只需要一个类的实例相同。如果您只需要一个实例,只需创建一个实例。 Singleton 所做的是强制您只能可以创建一个实例,无论您可能需要多少,或您的班级的其他客户可能需要,或者您将来或在测试条件下可能需要多少。 ... 基本上是只需要一个和只需要一个之间的区别。不要仅仅因为前者是真的就实施后者。【参考方案3】:

你的类没有数据成员,所以我看不出有什么好的理由使用一个类:

namespace AA

    void a1          ();
    std :: string b1 ();
    std :: string c1 (unsigned short x);
;

当然我需要至少有一个对象才能调用这个类的函数

那不是真的。您可以在没有类实例的情况下调用静态成员函数。

关于单例模式的说明:它名声不好,经常被误用,而且根据我的经验,它很少有用。它的作用是强制该类只能有一个实例,并且该实例是全局可访问的。

人们经常认为,“我只需要一个实例,因此我应该使用 Singleton”,尤其是当 Singleton 是他们被引入的第一个大写设计模式时。这是错误的——如果您只需要一个实例,请创建一个实例并使用它。不要不必要地限制该类的所有未来用户只创建一个实例。不要不必要地创建共享的全局状态。这两件事都会使您的代码不那么灵活,更难以不同的方式使用,因此特别难以测试。有些人会争辩说,由于这些原因,Singleton 严格来说从不有用。

在这种情况下,您似乎甚至不需要一个实例。如果是这种情况,我会使用上述免费功能。

【讨论】:

请在您的回答中将您的评论信息放在Als的回答下。我觉得它很有价值。

以上是关于当不需要创建多个对象时,是不是应该将类的成员变为静态?的主要内容,如果未能解决你的问题,请参考以下文章

PHP学习笔记---封装(面向对象三大特性之一)

C++类的定义和创建

java(内部类)

C++ 特殊类的设计

JPA 选择,啥应该延迟加载,当不需要时

请问含有多个对象成员的派生类的构造函数执行时不是先执行基类么?为啥这个先输出的是“正式生是”这个