如何制作一个可被所有东西引用的对象?

时间:2018-01-31 02:04:30

标签: c++ inheritance

我正在尝试创建一个只被实例化一次的类ShapeManager,并且有一个基类Shape(及其所有子项)都可以访问它。这将导致结构如下所示:

ShapeManager
Shape
Square
Triangle
Circle

#include "Shape.h" // so that i can use Shape in the vector

// This is instantiated once in main
class ShapeManager {
public:
    typedef std::vector<std::unique_ptr<Shape>> VecShape;
    typedef std::default_random_engine          DRE;

private:
    VecShape&   m_shapes;
    b2World&    m_world;
    DRE&        m_gen;

public:
    ShapeManager(VecShape& vectorShapes, b2World& world, DRE& gen) 
        : m_shapes(vectorShapes), m_world(world), m_gen(gen) {}

    VecShape& getShapeList() { return m_shapes; }
    b2World& getWorld() { return m_world; }
    DRE& getDRE() { return m_gen; }
};
#include "ShapeManager.h" // so that i can access it's member functions

class Shape {
protected:
    std::string m_name;

public:
    Shape() : m_name("Shape") {}
    std::string getName() { return m_name; }
};

我简化了我的代码以使其与我的问题保持相关。如果我不清楚我会问我会进一步解释它! 基本上我只想要一个管理我的形状对象的课程。保存Shape's个孩子将使用的数据,例如m_genm_world

编辑1:我创建ShapeManager的主要动机是存储对m_shapes,m_world和m_gen的引用,但我不希望每个形状对象都有这3个引用变量。这意味着创建一个Circle必须在ctor中包含这3个参数,以及与圆相关的参数。

编辑2:单例和/或依赖注入是两种设计模式,在实施时解决了我的问题。 Here is some info on it.谢谢大家!

2 个答案:

答案 0 :(得分:1)

不要尝试通过所有代码访问全局变量。使某个对象只能由需要它的人访问。因此,在Shape中创建一个私有ShapeManager并通过Shapes构造函数传递它。

Shape必须能够访问ShapeManager,这仍然很奇怪。

编辑 - 作者评论: 创建ShapeManager的主要动机是存储对m_shapes,m_world和m_gen的引用,但我没有不希望每个形状对象都有这3个参考变量。

你可以有一个存储你的3个引用变量的结构,每个需要访问它们的对象都有一个私有结构。

其他一些文件:

struct myManagers {
ShapeManager *shapeMan;
WorldManager *worldMan;
GenManager *genMan;
}

Shape.h:

#ifndef H_SHAPE // Include guards to avoid circular dependency
#define H_SHAPE
#include "ShapeManager.h" // so that i can access it's member functions

class Shape {
protected:
    std::string m_name;
    myManagers *myMan = nullptr;

public:
    Shape(myManagers *myManager) : m_name("Shape"), myMan(myManager) {}
    std::string getName() { return m_name; }
};

#endif

并且用法如下:

int main() {
myManagers GlobalManager;
GlobalManager.shapeMan = &ShapeManager;
// ... fill in other 2 managers

Shape myBall(&GlobalManager);
// this way myBall has access to all 3 references
}

ps:包含警卫几乎是唯一可以接受宏的场合

答案 1 :(得分:1)

您正在寻找的是 Singleton Design Pattern 。请参阅以下代码:

class ShapeManager
{
public:
static ShapeManager& instance()
{
    static ShapeManager *instance = new ShapeManager();
    return *instance;
}

private:
    ShapeManager(){}

/*
    use this space to fill in your code
    */
}

您可以访问班级成员:

ShapeManager::instance().getDRE();

这限制了该类的单个实例。没有必要实例化这个类的对象,事实上,你不能并且可以从任何地方访问它。