Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何避免对GUI后面的数据使用全局变量?_C++_Design Patterns_User Interface_C++11 - Fatal编程技术网

C++ 如何避免对GUI后面的数据使用全局变量?

C++ 如何避免对GUI后面的数据使用全局变量?,c++,design-patterns,user-interface,c++11,C++,Design Patterns,User Interface,C++11,我正在编写一个音频处理独立应用程序。我有一个AudioManager对象,它包装了与引擎相关的内容(如I/O设备管理、信号处理路由、运行状态)。我正在编写一个GUI来控制后台运行的AudioManager。目前,每个需要向AudioManager发送消息的组件都需要指向它的指针 当一个深度嵌套的对象需要指向AudioManager的指针时,这就开始变得疯狂,因为这意味着我需要通过GUI对象的构造函数传递指针,而这些GUI对象并不直接关心AudioManager(只有一些子组件需要知道) 我可以将

我正在编写一个音频处理独立应用程序。我有一个
AudioManager
对象,它包装了与引擎相关的内容(如I/O设备管理、信号处理路由、运行状态)。我正在编写一个GUI来控制后台运行的
AudioManager
。目前,每个需要向AudioManager发送消息的组件都需要指向它的指针

当一个深度嵌套的对象需要指向
AudioManager
的指针时,这就开始变得疯狂,因为这意味着我需要通过GUI对象的构造函数传递指针,而这些GUI对象并不直接关心
AudioManager
(只有一些子组件需要知道)

我可以将
AudioManager
设置为一个单例,以避免使用样板文件,但是来自类的信息流是双向的,所以这可能是个坏主意。我也觉得把所有的东西都放在一个大班里有点可疑,但这会让传递变得更容易。是否有一个共同的模式来避免无意识的指针传递

下面是一些伪代码,显示了一些强调问题基本类型的构造函数。我给这个C++11添加了标签,看看它是否提供了任何独特的解决方案

MainWindow()
{
    am = new AudioManager();
    someWidget = new SomeWidget(am);
}

SomeWidget(AudioManager* am_) //SomeWidget does not really care about am
{
    someSubComponent = new SubThingy(am_);
}

SubThingy(AudioManager* am_) : subThingyLocalAudioManagerPtr(am_)
{
    subThingyLocalAudioManagerPtr->registerSomethingOrOther(this);
}
在您的示例中,“SomeWidget”应该采用其实际依赖关系“SomeThingy”,而不是AudioManager

通常,当您看到整个世界都在引用一个类时,这意味着该类做得太多了。名称“XyzManager”通常表示出于相同原因的问题。(类应该以它们所做的事情命名,如果描述它所做事情的最具体的名称是“Manage”,那么它应该是单独的类)

可能会有所帮助。它还有助于解决所有权问题,并且免费获得更好的可测试性,因为它使模拟类变得更容易

其想法是将所有资源分配转移到工厂;您的类构造函数只接受指向其直接依赖项的(智能)指针

大致如下:

#include <memory>
using namespace std;

class SubThingy;

class AudioManager { 
  public:
    void registerSomethingOrOther(SubThingy* st) { };
};

// None of the ctors do resource allocation
class SubThingy { 
  public:
    SubThingy(AudioManager* am) : subThingyLocalAudioManagerPtr(am)
    {
      subThingyLocalAudioManagerPtr->registerSomethingOrOther(this);
    };
  private:
    // raw pointer, we don't own it 
    AudioManager* subThingyLocalAudioManagerPtr; 
}; 

class SomeWidget { 
  public:
    // only takes DIRECT depencies
    SomeWidget(unique_ptr<SubThingy> st) : someSubComponent(move(st)) { } 
  private:
    // SomeWidget owns someSubComponent
    unique_ptr<SubThingy> someSubComponent;
};

class MainWindow { 
  public:
    // only takes DIRECT depencies
    MainWindow(unique_ptr<SomeWidget> sw) : someWidget(move(sw)) { }
  private:
    // MainWindow owns its widgets
    unique_ptr<SomeWidget> someWidget; 
};

class Factory { // All memory allocations happen in the factory
  public:
    static unique_ptr<MainWindow> createMainWindow(AudioManager* am) 
    {
      unique_ptr<SubThingy> someSubComponent{ new SubThingy(am) };

      unique_ptr<SomeWidget> someWidget{ new SomeWidget(move(someSubComponent)) };

      return unique_ptr<MainWindow>(new MainWindow(move(someWidget))); 
    }
};

int main() {
  // not clear from the example who owns / should own the audio manager
  AudioManager* am = nullptr;

  auto mainWindow{ Factory::createMainWindow(am) };
}
#包括
使用名称空间std;
类次思维;
类音频管理器{
公众:
无效寄存器somethingorother(SubThingy*st){};
};
//没有一个部门进行资源分配
类子语法{
公众:
子主题(AudioManager*am):子主题本地AudioManager(am)
{
子内容LocalAudioManagerPtr->RegisterSomethingOther(此);
};
私人:
//原始指针,我们不拥有它
AudioManager*子内容LocalAudioManager;
}; 
类{
公众:
//只接受直接依赖
SomeWidget(unique_ptr st):someSubComponent(move(st)){}
私人:
//SomeWidget拥有someSubComponent
唯一的子组件;
};
类主窗口{
公众:
//只接受直接依赖
主窗口(唯一的\u ptr sw):someWidget(移动(sw)){}
私人:
//MainWindow拥有自己的小部件
独特的_ptrsomewidget;
};
类工厂{//所有内存分配都发生在工厂中
公众:
静态唯一\u ptr CreateMain窗口(AudioManager*am)
{
唯一_ptr someSubComponent{new SubThingy(am)};
唯一的_ptrsomewidget{new someWidget(move(someSubComponent))};
返回唯一的ptr(新主窗口(移动(someWidget));
}
};
int main(){
//示例中不清楚谁拥有/应该拥有音频管理器
AudioManager*am=nullptr;
自动主窗口{Factory::createMainWindow(am)};
}
现在,复杂性将出现在您的工厂类中,但至少混乱将限于一个地方

如果工厂太大,你可以把它分成不同的类;甚至更好的是,有不同的工厂生产不相关的东西:一个生产东西的工厂,另一个生产小部件的工厂,等等


我同意比利的观点,有一个经理在身边是一个班级试图做太多事情的标志,应该修改设计。不幸的是,如果上帝对象生活在第三方库中,而您无法控制它…:(

但这仍然是一个全局。您的全局只是变成了“工厂”而不是AudioManager实例。感谢您提供有趣的视角+1@BillyONeal是的,我同意,有一个经理在身边是一个阶级试图做太多事情的标志,设计应该修改。至于工厂,你可以把一个大的、巨大的工厂分成不同的阶级;或者更好的是,让不同的工厂处理无关的事情,一家工厂生产东西,另一家工厂生产小部件等。@learnvst我已经对我的答案进行了重大修改,请阅读。希望这有助于修改您的设计。@Ali非常感谢您的编辑。这真的帮助了我重新设计。代码已经到了让我痛苦的地步,所以我肯定需要回到理论上来。So音频管理器就是现在孩子们称之为音频播放器的东西。很有趣。现在的孩子们就是这么做的。很有趣。机器人不是“trolling”,他是在暗示将事物称为“managers”的荒谬.这几乎总是一个糟糕设计的标志。你甚至得到了一个明确的答案。我完全同意这个设计很糟糕-这就是我来乞求的原因:)