首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决全球接入问题?

如何解决全球接入问题?
EN

Stack Overflow用户
提问于 2009-09-10 04:45:07
回答 7查看 1.1K关注 0票数 1

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

在我的应用程序中,需要有UiConnectionListUiReaderUiNotifier类的一个实例。

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

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

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

示例代码:

方法1

文件:uiconnectionlist.h

代码语言:javascript
复制
#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

文件:uinotifier.h

代码语言:javascript
复制
#ifndef UINOTIFIER_H
#define UINOTIFIER_H

class UiNotifier
{
public:
    UiNotifier();
};

namespace Globals {
    UiNotifier uiNotifier;
}

#endif // UINOTIFIER_H

方法2:

文件:uiconnectionlist.h

代码语言:javascript
复制
#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

文件:uinotifier.h

代码语言:javascript
复制
#ifndef UINOTIFIER_H
#define UINOTIFIER_H

class UiNotifier
{
public:
    UiNotifier();
};

#endif // UINOTIFIER_H

文件:globals.h

代码语言:javascript
复制
#ifndef GLOBALS_H
#define GLOBALS_H

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

namespace Globals {
    UiConnectionList connectionList;
    UiNotifier uiNotifier;
}

#endif // GLOBALS_H

我的问题

做这件事的更好的方法是什么?

PS:我不认为独生子女是正确的答案,对吗?

谢谢

好的,有两个答案告诉我要制作UiConnectionListUiNotifier的实例,可以选择将其包装在UiContext中,并在需要的地方传递。

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

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

谢谢

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-09-10 05:53:57

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

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

票数 4
EN

Stack Overflow用户

发布于 2009-09-10 04:52:43

我不会在全局范围内这样做,而是在主目录中创建三个对象,并将它们传递到需要的地方。对于其他程序员来说,它更容易理解,因为他看到了使用它们的时间/位置。它还使您能够更好地控制何时创建和销毁它们,而不是声明它们是全局的。

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

票数 2
EN

Stack Overflow用户

发布于 2009-09-10 06:55:12

首先,你是对的。这个问题与Singleton模式无关。这是一个班级设计的问题。

在这种情况下,我想要一个与您不同的实现。在这两个示例中,您都使用了一个名为“全局”的命名空间。这违反了单一关注原则,因为这里有许多对象没有其他共同点,只有全局可访问的单个对象。与其这样做,不如将您的单例封装在类声明本身中。

看看这个:

代码语言:javascript
复制
class UiConnectionList : public QObject
{
    Q_OBJECT

public:
    static UiConnectionList Connections; // This is your global varaible

public:
    UiConnectionList();

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

};

现在可以通过UiConnectionList::Connections访问全局连接。作为静态变量的单例实现并不是很好,应该做得更好。特别是为了防止指针的更改。但这是一个不同的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1403410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档