C++ 如何解决全球接入问题?

C++ 如何解决全球接入问题?,c++,design-patterns,global-variables,C++,Design Patterns,Global Variables,我正在开发一个应用程序,我需要SO社区在设计问题上的智慧 在我的应用程序中,类UiConnectionList、UiReader和UiNotifier只需要一个实例 现在,我想出了两种方法: 方法1: 每个文件在头文件本身中都有该类的全局实例 方法2:有一个单独的globals.h文件,其中包含每个类的单个全局实例。 示例代码: 方法1 文件:uiconnectionlist.h #ifndef UICONNECTIONLIST_H #define UICONNECTIONLIST_H #i

我正在开发一个应用程序,我需要SO社区在设计问题上的智慧

在我的应用程序中,类
UiConnectionList
UiReader
UiNotifier
只需要一个实例

现在,我想出了两种方法:

方法1: 每个文件在头文件本身中都有该类的全局实例

方法2:有一个单独的globals.h文件,其中包含每个类的单个全局实例。

示例代码: 方法1

文件:
uiconnectionlist.h

#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H

#include <QObject>
#include <QList>

class UiConnection;

class UiConnectionList : public QObject
{
    Q_OBJECT
public:
    UiConnectionList();

    void addConnection(UiConnection* conn);
    void removeConnection(UiConnection* conn);
private:
    QList<UiConnection*> connList;
};

namespace Globals {
    UiConnectionList connectionList;
}

#endif // UICONNECTIONLIST_H
#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H

#include <QObject>
#include <QList>

class UiConnection;

class UiConnectionList : public QObject
{
    Q_OBJECT
public:
    UiConnectionList();

    void addConnection(UiConnection* conn);
    void removeConnection(UiConnection* conn);
private:
    QList<UiConnection*> connList;
};

#endif // UICONNECTIONLIST_H
方法2:

文件:
uiconnectionlist.h

#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H

#include <QObject>
#include <QList>

class UiConnection;

class UiConnectionList : public QObject
{
    Q_OBJECT
public:
    UiConnectionList();

    void addConnection(UiConnection* conn);
    void removeConnection(UiConnection* conn);
private:
    QList<UiConnection*> connList;
};

namespace Globals {
    UiConnectionList connectionList;
}

#endif // UICONNECTIONLIST_H
#ifndef UICONNECTIONLIST_H
#define UICONNECTIONLIST_H

#include <QObject>
#include <QList>

class UiConnection;

class UiConnectionList : public QObject
{
    Q_OBJECT
public:
    UiConnectionList();

    void addConnection(UiConnection* conn);
    void removeConnection(UiConnection* conn);
private:
    QList<UiConnection*> connList;
};

#endif // UICONNECTIONLIST_H
文件:
globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include "uiconnectionlist.h"
#include "uinotifier.h"

namespace Globals {
    UiConnectionList connectionList;
    UiNotifier uiNotifier;
}

#endif // GLOBALS_H
我的问题 这样做的更好/正确的方法是什么

附言:我不认为单身汉是正确的答案,是吗

谢谢


好的,有两个答案告诉我创建
UiConnectionList
UiNotifier
的实例,可以选择将其包装在
UiContext
中,并在需要的地方传递

有人能列举一下为什么传递上下文比拥有全局可访问的变量更好的原因吗(用例子)

这将帮助我判断哪种方法更好(或更适合我的应用程序)


谢谢

您至少可以创建一个UiContext类/结构。将所有其他内容定义为此类的成员变量。然后在主类中创建UiContext实例,并将其传递给需要它的任何类。

您至少可以创建UiContext类/结构。将所有其他内容定义为此类的成员变量。然后在主类中创建UiContext的实例,并将其传递给需要它的任何类。

我不会全局执行它们,而是在主类中创建三个对象,并将它们传递到需要它们的任何地方。对于其他程序员来说,这更容易理解,因为他知道何时何地使用它们。它还可以更好地控制何时创建和销毁它们,而不是将它们声明为全局


编辑:澄清通常情况下,随着时间的推移,程序变得越来越复杂,代码由对设计等有不同想法的不同开发人员添加。一般来说(IMHO),一旦你开始在程序中引入全局变量,它会鼓励其他程序员也这样做。这就是为什么我更喜欢将数据传递到使用它的任何地方,以过程语言作为参数,或通过ctor以OOP语言传递。这样可以更容易地查看依赖项。

我不会对它们进行全局处理,而是在main中创建三个对象,并将它们传递到任何需要它们的地方。对于其他程序员来说,这更容易理解,因为他知道何时何地使用它们。它还可以更好地控制何时创建和销毁它们,而不是将它们声明为全局


编辑:澄清通常情况下,随着时间的推移,程序变得越来越复杂,代码由对设计等有不同想法的不同开发人员添加。一般来说(IMHO),一旦你开始在程序中引入全局变量,它会鼓励其他程序员也这样做。这就是为什么我更喜欢将数据传递到使用它的任何地方,以过程语言作为参数,或通过ctor以OOP语言传递。这样可以更容易地查看依赖项。

更好的方法是使用Singleton方法。它已经过测试和证明。此外,如果我在本地范围内定义了另一个UiConnectionList变量,则该类将失败

void myfunction()
{
    UiConnectionList connectionList;
    // Any usage to connectionList would be cleared after this function exits.
}
创建singleton类时请始终记住。锁(Private tify?)四大类:构造函数、复制构造函数、赋值运算符、析构函数

另外,因为您使用的是全局变量,所以我假设您不需要作用域或隐藏。因此,单例方法是更好的方法

下面是一个实现单例的示例

// Meyers singleton
static UiConnectionList* UiConnectionList::getSingletonPtr()
{
    static UiConnectionList x;
    return &x;
}

更好的方法是使用Singleton方法。它已经过测试和证明。此外,如果我在本地范围内定义了另一个UiConnectionList变量,则该类将失败

void myfunction()
{
    UiConnectionList connectionList;
    // Any usage to connectionList would be cleared after this function exits.
}
创建singleton类时请始终记住。锁(Private tify?)四大类:构造函数、复制构造函数、赋值运算符、析构函数

另外,因为您使用的是全局变量,所以我假设您不需要作用域或隐藏。因此,单例方法是更好的方法

下面是一个实现单例的示例

// Meyers singleton
static UiConnectionList* UiConnectionList::getSingletonPtr()
{
    static UiConnectionList x;
    return &x;
}

在globals.h中使用时,对于您使用的每个编译单元(.cc或.cpp文件),您将拥有globals::UiConnectionList和globals::UiNotifier的多个定义。这是而不是制作这些类别的一个实例的方法。你应该像以前的海报建议的那样使用单例模式


如果您不想使用singleton模式,正确的方法是在一个编译单元中定义两个类,然后在头文件中将它们声明为extern,结果是您想要的类的一个全局实例,但这不会阻止它被复制或复制构造。从您的示例中,您不知道声明和定义之间的区别。

在globals.h中使用时,对于您使用的每个编译单元(.cc或.cpp文件),您将拥有globals::ui连接列表和globals::ui通知符的多个定义。这是而不是制作这些类别的一个实例的方法。你应该像以前的海报建议的那样使用单例模式

如果您不想使用singleton模式,正确的方法是在一个编译单元中定义两个类,然后在头文件中将它们声明为extern,结果是您想要的类的一个全局实例,但这不会阻止它被复制或复制构造。从你的