【问题标题】:How to have multiple classes share pointers to a common class如何让多个类共享指向公共类的指针
【发布时间】:2015-03-06 08:10:46
【问题描述】:

我正在尝试确定解决设计问题的正确方法,但我正在努力寻找“正确”的方法。

简单来说:

  • 我有多个功能类,每个类都需要与多个公共类交互。 (全部使用 New 在堆上创建)

例如

A class [a] object needs to be able to call methods in class [x], [y] & [z] objects
A class [b] object needs to be able to call methods in class [x], [y] & [z] objects
A class [c] object needs to be able to call methods in class [x], [y] & [z] objects

到目前为止,我有 3 个解决方案:

  1. 使公共类 (x, y, z) 成为全局对象(或单例),以便功能类 (a, b, c) 可以直接调用对象。但是,我不喜欢让事情全球化的想法。
  2. 在初始化期间将指向公共类(x、y、z)的指针传递给每个功能类(a、b、c)以供以后使用。但是,如果删除公共类,则功能类的指针会过时。
  3. 拥有一个“管理”公共类(x、y、z)的全局对象(可能是单例),并且功能类(a、b、c)在需要时从这里请求公共类指针全局对象。这使他们可以立即知道指针是否为 NULL。

以前,我使用过 (2),但随着时间的推移,我对这种方法感到不满意。

我认为我目前更喜欢 (3),但仍然对拥有全局对象/单例感到不舒服。

我一直在寻找适合这种场景的设计模式,但找不到任何适合的设计模式,可能是因为不知道正确的关键字。

这个问题是否有通用的设计方法/模式?

【问题讨论】:

  • 也许你应该阅读一下std::shared_ptr
  • 有什么理由你不能做 (2) 然后(按设计)确保你在 x、y 和 z 之前处理 a、b 和 c?
  • 当驱动设计模式使用的问题未知时,无法给出建议。
  • 当你真正应该谈论对象时,你却在谈论类!没有什么永远不会删除一个类,并且永远不会在堆上创建一个类,只有对象是。但是当您考虑使用单例或全局对象时,您是否可以只使用真实类的静态方法(和字段) - 即不创建对象?
  • 您不能将对象 x,y,z 作为您在 a,b,c 中调用的函数的参数传递吗?

标签: c++ class pointers design-patterns


【解决方案1】:

如果没有看到问题的更多细节,很难提供建议,但根据你所说的,我会选择选项 2。

如果生命周期管理得当,最好使用 RAII 和资源管理对象,那么在删除功能类之前没有理由删除公共类。

你说所有类都是用new 在堆上创建的,但你可以使用std::unique_ptr 之类的东西来管理生命周期:

#include <memory>

struct X { };
struct Y { };
struct Z { };

class A {
    X* x_;
    Y* y_;
    Z* z_;
  public:
    A(X* x, Y* y, Z* z) : x_(x), y_(y), z_(z) { } 
    void doSomething() { /* use x_, y_ and z_ ... */ }
};

// Similarly for B and C ...

int main() {
    auto x = std::make_unique<X>();
    auto y = std::make_unique<Y>();
    auto z = std::make_unique<Z>();

    auto a = std::make_unique<A>(x.get(), y.get(), z.get());
    a->doSomething();
}

如果 x,yz 总是一起使用或者应该懒惰地创建,你可以使用类似于选项 3 的东西并将它们组合成一个“管理”对象,但我会避免使该管理对象成为全局对象/singleton 如果可以的话,只需通过引用或指针将其传递到功能类的初始化中,如选项 2 所示:

struct XYZ {
  std::unique_ptr<X> x;
  std::unique_ptr<Y> y;
  std::unique_ptr<Z> z;
  XYZ():x(std::make_unique<X>()), y(std::make_unique<Y>()), z(std::make_unique<Z>()){}
};

class A {
    XYZ* xyz_;
  public:
    A(XYZ* xyz) : xyz_(xyz) { } 
    void doSomething() { /* use xyz_ ... */ }
};

// Similarly for B and C ...

int main() {
    XYZ xyz;
    auto a = std::make_unique<A>(&xyz);
    a->doSomething();
}

【讨论】:

    猜你喜欢
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 2021-08-21
    相关资源
    最近更新 更多