1

我是 C++ 新手,这让我有点困惑我试图理解一些代码源,它正在做类似的事情

使用 3 个静态指针指向 3 个类,将 3 个指针从 main 分配给这 3 个类,使用它们访问他们创建的类实例的成员 为什么不只使用实例?所以他们在堆栈上创建它而不是在没有函数范围的堆上创建它?它已经在 main 这里是代码源

int _tmain(int argc, _TCHAR* argv[])
{

...

    SetConsoleTextAttribute(hStdOut, FOREGROUND_CYAN);
    printf("Creating Database... ");
    CDatabaseRoot::Create();
    SetConsoleTextAttribute(hStdOut, FOREGROUND_LIME);
    WriteLn("Completed.");

    SetConsoleTextAttribute(hStdOut, FOREGROUND_CYAN);
    printf("Creating Servers... ");
    CDatabaseRoot::AuthServer->Port = 9958;
    CDatabaseRoot::AuthServer->OnClientConnect = AuthConnect;

在 CDatabaseRoot 的最后

class CDatabaseRoot
{
public:
    static CDatabaseRoot* Core;
    static CServerSocket* AuthServer;
    static CServerSocket* GameServer;
    static void Create();
    static void Destroy();

在 cpp

CDatabaseRoot* CDatabaseRoot::Core;
CServerSocket* CDatabaseRoot::AuthServer;
CServerSocket* CDatabaseRoot::GameServer;
void CDatabaseRoot::Create()
{
    CDatabaseRoot::Core = new CDatabaseRoot();
    CDatabaseRoot::AuthServer = new CServerSocket();
    CDatabaseRoot::GameServer = new CServerSocket();
}

为什么这样做?有没有更好的方法来完成它?我想要一些解释,谢谢

4

3 回答 3

2

静态成员意味着它们在类的所有实例之间共享。由于该类持有的可能是唯一实例CDatabaseRoot,因此看起来代码正在实现单例模式(尽管它没有通过在创建之前检查 null 来强制执行它,因此Create()多次调用而不调用相应的Destroy()可能会导致问题) . 公开数据成员通常也被认为是不好的形式和错误的秘诀。

有几种方法可以在 C++ 中实现单例。请参阅 Alexandrescu 的Modern C++ Design了解一些变体(代码可在此处获得),并参阅上面提到的 Wikipedia 文章了解其他几个。

于 2013-06-18T15:22:12.233 回答
2

似乎这样做是为了使除 main 之外的方法可以访问这些全局服务,而无需将它们作为参数传入。类似于 Singleton 模式,但没有保护(如果“Create”被调用两次会发生什么?)。

首先是个坏主意。所以你很聪明地看那个代码并有点怀疑。

我建议改为定义一个封装这些服务的“上下文”结构(或类):

struct Context
{
    CDatabaseRoot* Core;
    CServerSocket* AuthServer;
    CServerSocket* GameServer;
};

您将在 main 中初始化它,然后将其传递给任何需要它的类或对象。

于 2013-06-18T15:26:22.347 回答
1

如果构造函数检查以确保只存在对象的一个​​实例,如果存在则返回它而不是创建一个新实例,这将实现单例模式,但事实并非如此。正如其他回答者所说,您的类的任何实例都将共享这些静态指针的相同实例。如果这些对象是方法,那么您可以调用这些方法而无需先创建对象的实例,因为它们是静态的,但那是另一个主题。

于 2013-06-18T15:27:21.900 回答