单身中的一切都可以是静态的吗?

时间:2012-12-11 01:54:31

标签: c++ static singleton

在C ++中,单例中的所有成员都可以是静态的,还是尽可能的?我的想法是,无论如何全球只有一个例子。

在搜索时我确实在C#中找到了很多关于静态类的讨论,但对此并不熟悉。想了解它。

无论您有什么想法,请发表评论。

5 个答案:

答案 0 :(得分:6)

使用静态单例时,您无法控制何时分配和构造单个单元。这使你受静态变量的构造规则的c ++顺序的支配,所以如果你碰巧在构造另一个静态变量期间调用这个单一,那么单个可能还不存在。

如果您没有打算从另一个静态变量的构造函数中调用单例,并且不希望因任何原因而延迟构造,那么对单例使用静态变量就没问题了。

有关详细信息,请参阅Static variables initialisation order

答案 1 :(得分:1)

您可能知道,单例模式包含一个静态方法Instance,当且仅当它存在并返回该实例时才会创建该实例。单身的其他或所有方法都没有理由不是静态的。但是,鉴于该类只有一个实例,我不确定将其他所有内容都设置为静态。这有意义吗?

答案 2 :(得分:1)

单身人士的大部分要点是对其创建时有一定的控制权。

对于那些成员,使用静态数据成员可以放弃该控件。

所以做起来并不聪明。

也就是说,单身人士通常是邪恶的,有许多与纯粹的全球变量相同的问题,包括倾向于作为一个无法控制的通信中心,传播各种不可预测的影响,而不是从不可预测的地方传播到其他不可预测的地方,而且很大程度上是未知的地方,在不可预测的时间。

因此,仔细思考它是一个好主意:单身真的答案,或者就目前的情况而言,它只是一种解决问题的方法。解决?

答案 3 :(得分:1)

回答你的问题:你建议的情况更像是C#中的“静态类”,而C ++没有“静态类”的概念。

通常在C ++单例类中,唯一的静态数据成员是单例实例本身。这可以是指向单例类的指针,也可以只是一个实例。

有两种方法可以创建单例类,而单例实例不是指针。

1)

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        static MySingletonClass instance;
        return instance;
    }

    // non-static functions

private:
    // non-static data-members
};

2)

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        return sInstance;
    }

    // non-static functions

private:
    static MySingletonClass sInstance;
    // non-static data-members
};
// In CPP file
MySingletonClass MySingletonClass::sInstance;

此实现不是线程安全的,无法根据构造时间或销毁时间进行预测。如果此实例依赖于另一个单例来破坏自身,则在退出应用程序时可能会导致无法识别的错误。

带指针的那个看起来像这样:

class MySingletonClass
{
public:
    static MySingletonClass& getInstance()
    {
        return *sInstance;
    }
    static MySingletonClass* getInstancePointer()
    {
        return sInstance;
    }

    MySingletonClass()
    {
        if (sInstance) {
            throw std::runtime_error("An instance of this class already exists");
        }
        sInstance = this;
    }

    // non-static functions

private:
    static MySingletonClass* sInstance;
    // non-static data-members
};

这种单例类的初始化通常会在应用程序初始化期间发生:

void MyApp::init()
{
    // Some stuff to be initalized before MySingletonClass gets initialized.
    MySingletonClass* mySingleton = new MySingletonClass(); // Initalization is determined.
    // Rest of initialization
}

void MyApp::update()
{
    // Stuff to update before MySingletonClass
    MySingletonClass::getInstance().update(); // <-- that's how you access non-static functions.
    // Stuff to update after MySingletonClass has been updated.
}

void MyApp::destroy()
{
    // Destroy stuff created after singleton creation
    delete MySingletonClass::getInstancePointer();
    // Destroy stuff created before singleton creation
}

虽然在这种情况下控制单身的初始化和破坏,但单身人士在多线程应用中表现不佳。我希望这能解决你的疑虑。

答案 4 :(得分:0)

答案简短:是的!确定! C ++很灵活,几乎一切皆有可能(特别是这么简单的事情)。

详细答案取决于您的使用案例。

  • 其他静力/全局变量如何取决于你的标志
  • 当第一次访问你的单身人士时(可能在主?之前)?
  • 你必须考虑很多其他事情(大多数都与你的单身人士与其他实体的互动有关)