如何在没有A全局的情况下访问A :: member()?

时间:2012-08-14 20:02:59

标签: c++ oop architecture

在A类中,我有一个成员需要每n毫秒访问数百或数千次,例如需要访问LPDIRECT3DDEVICE3D以绘制任何内容。

用于拥有全局但似乎不对。在我的研究中,我找到了OP问题的答案:

  

jalf“这很痛苦,所以这是一个警钟:我做错了。很多对象不应该知道屏幕缓冲区。我该如何解决这个问题?`)“ @ this answer alinea 8

基本上我想知道如何处理这样一个全局变量,还有其他选择吗?

3 个答案:

答案 0 :(得分:0)

一个好的方法是让你想要使用A :: member的对象在构造时注册自己的数据结构(弱指针或原始指针的矢量,指针映射等等),然后当你想要将A :: member应用于每个对象,您可以遍历所有已注册的对象并处理每个对象的请求。注意,在这里使用全局变量很容易陷入陷阱 - 尽量避免使用它。

如果你有不同类型的对象(没有继承层次结构),你可以使用类型擦除为每个对象存储函数指针(或函数对象,如boost :: function),这将占用A :: member并将其应用于宾语。这将允许任何抽象对象使用A :: member而无需知道x个对象的类型。获取匹配的函数可以像为每个对象添加类似的格式化成员函数一样简单,也可以使用boost :: bind来包装调用,使工作成为匹配的格式。

这种方法消除了大量的样板代码,并且使用各种新的对象类型可以轻松扩展,以便在某些指定的通知时间使用A :: member。

答案 1 :(得分:0)

  

我能想到的一件事是将A :: member传递给所有需要访问它的函数,但这将是一个荒谬的数量。

有很多方法 - 它们都是你每天使用的程序。

  • 你可以持有参考
  • 传递参​​考(如您所述)
  • 在某些情况下使用多个实例
  • 使用方法来抽象实际需要3个调用来调用该方法的事实(最少知识原理)
  • 使用更小,更专业的对象
  • 考虑其他形式的抽象和/或包装
  • 在某些地方考虑其他设计模式

刚刚开始编写程序 - 不是盲目的,因为你可能最终得到高耦合 - 观察使用模式,重构和相应的重组。这是全局变坏的一个原因 - 它们很难根除,但这几乎是删除一个有很多引用的过程所必须经历的过程。

答案 2 :(得分:0)

您的选择归结为:如果某个功能需要数据,那么该数据必须:

  1. 作为参数传递给函数,或
  2. 位于函数可以有效查询的位置。
  3. (我将忽略3.或由函数本身生成。)

    如果您想通过A::member,您有几种选择。您可以将数据放在上下文对象中并传递它(如果您想要传递一些这些成员,这可能会有效,并且在单元测试的情况下恰好可以正常工作)。您可以将数据直接传递给函数。您可以将数据传递给将其传递给函数的内容。您可以使用消息传递。您可以使用更多间接机制,如发布/订阅队列。您可以选择这些中介对他们传递的数据类型有多少了解。当您将数据从一个地方传递到另一个地方时,所有这些都意味着源,传输和目标之间的各种耦合。最好这种耦合可能会引起大规模的刺激;在最坏的情况下,这可能是一个严重的设计或安全漏洞。

    如果您想将A::member放在可以查询的地方,您还有几个选项。全局变量是一个。可以访问的数据存储(例如,文件,数据库,服务,高速缓存,HTTP资源)是另一种。其中每个都有影响:您需要考虑谁可以访问数据以及如何访问。如果访问很容易(如全局变量),那么就会遇到如何在不破坏数据客户端的情况下改进系统的问题。在测试代​​码时,您可能还会遇到问题。最好这种耦合可能会引起大规模的刺激;在最坏的情况下,它可能是一个严重的设计缺陷,并导致几乎不可测试的代码。

    如果您想传递数据,但又不想要传递数据,那么您的另一个攻击角度是限制需要数据的函数数量。即合并代码,以便更少的代码片段实际需要了解A::member。 Facade,Bridge,Observer和Abstract Base Class等各种模式可以在语言层面为您提供帮助。诸如Publish-Subscribe和Callback之类的架构模式也可以提供帮助。研究解耦重构依赖性消除等主题,以获取灵感。

    那么这些是正确的方法呢?没有一个正确的方法。您需要查看您的具体案例,权衡该案例的选项和权衡,并选择您最喜欢的案例。