C ++中静态和全局的替代方案?

时间:2015-04-27 07:43:53

标签: c++ static global qgraphicsitem qgraphicsscene

我有一个需要其他类访问的类实例。

  • 将实例始终传递到构造链中会非常麻烦。
  • 我试图避免全局变量,因为人们倾向于反对这一点。
  • 我以为我声明这个实例是一个类的静态成员,然后包含这个类以便访问该实例,但这不起作用

error: calling a private constructor of class 'Foo'

要在QGraphicsView框架的上下文中进一步指定问题: 我想添加QGraphicsItems,它由控制器类(管理项目)实例化到QGraphicsScene,这是(但我不坚持那个细节)我的QMainWindow类的成员。

我花了相当多的时间在互联网上搜索,但我很新,而且有点困在这里。对于解决困境的最佳方法,我表示感谢。

2 个答案:

答案 0 :(得分:2)

对全局变量的使用引起了极大的争议,这就是为什么我要指出的原因,我在下面写的是我的个人观点并且可以讨论。

我不知道在没有全局对象的情况下传递实例来解决问题。我个人并不认为全球实例在任何情况下都是邪恶的。

  1. 当我设计一个库时,我倾向于避免除一个工厂之外的全局对象。全局对象通常用作不需要快捷方式的快捷方式,或者避免为程序员键入一些内容。此外,库中的大多数类应该是独立的。如果在这些类中使用全局实例,则会牺牲独立性。

  2. 当我在类中使用静态时,如果整个类是单例或工厂方法(例如create或get),我只使用它们。永远不会以你描述的方式。在您描述它的方式中,对于其他开发人员来说这是意料之外的,因为您需要第三方来初始化该静态对象。除了避免输入更长的构造函数之外,你什么也得不到。这不是目标。

  3. 如果我使用全局实例,我总是将它包装在管理类中。我从不像QGraphicsItems那样直接使用第三方类作为全局(也没有“原始”类或类型)。与第2点一样,其他人可能并不认为这是全球性的。更重要的是,不清楚谁必须填补或杀死该实例。 “GraphicsItemManager”可以有一个“设置”方法,使第三个用户完全清楚。

  4. 传递实例不是每种情况下恕我直言的最佳方式。并非所有课程都可以重复使用,它们仅适用于一个项目。在这里,实现的速度,易用性和明确的分组价值超过了“没有全局”的教条。大部分时间我都会编写管理器类,这些类对例如图形项目。只要我使用之前指出的规则,我就没有让代码可读性降低的感觉。

  5. 有时资源在构造时间内不可用,因此您已经传递了一个包装器。这导致您通过类传递实例,这些类本身不需要该资源,或者它们自己是库的一部分(在这种情况下,通常您无法更改构造函数)。这可能(因为我们都是人类)导致误解。我使用全局管理类来跳过那些“gabs”,因为我认为保持该空间不受依赖关系的影响更大。

  6. 正如我写的恕我直言。

答案 1 :(得分:0)

当你有一个设计,其中类A创建了类B,创建了类C,需要在其构造函数中接受类D的实例时,会出现此问题。然后,您必须将D一直传递到ABC。如果您将设计更改为具有创建实例功能(在主要或工厂类中),该功能知道如何创建ABCD 。然后你可以按如下方式编写这个函数:

D d;
C c(d);
B b(c);
A a(b);

这样每个类只接受它的依赖。

如果您后来意识到B也需要使用类D,那么您只需更改B的构造函数,而不会影响A的构造函数。