c++ - 寻找更好的方法将静态列表集成到一组类中

标签 c++ static-methods

我正在尝试将我儿子的兴趣从《魔兽争霸 3》编程扩展到 C++,以在一定程度上拓宽他的视野。我们正计划移植他写的一个小游戏。

上下文是这样的。

  • 有舰船和导弹,舰船将使用导弹并与其互动
  • 存在一个容器,其中将容纳“一系列”船舶。
  • 存在一个容器,其中包含行星的“列表”。
  • 可以对容器中的所有元素应用函数 (for_each)
  • 可以随时创建/摧毁船只和导弹
  • 新对象会自动将自身插入到正确的容器中。

我拼凑了一个小例子来完成这项工作,因此我们可以讨论主题(列表、模板等),但我对结果不满意。

#include <iostream>
#include <list>
using namespace std;

/* Base class to hold static list in common with various object groups */ 
template<class T>
class ObjectManager
{
    public :
        ObjectManager(void)
        {
            cout << "Construct ObjectManager at " << this << endl;

            objectList.push_back(this);
        }

        virtual ~ObjectManager(void)
        {
            cout << "Destroy ObjectManager at " << this << endl;
        }

        void for_each(void (*function)(T *))
        {
            for (objectListIter = objectList.begin(); 
                 objectListIter != objectList.end(); 
                 ++objectListIter)
            {
                (*function)((T *) *objectListIter);
            }
        }
               list<ObjectManager<T> *>::iterator objectListIter;
        static list<ObjectManager<T> *>           objectList;
};

/* initializer for static list */ 
template<class T>
list<ObjectManager<T> *> ObjectManager<T>::objectList;


/* A simple ship for testing */ 
class Ship : public ObjectManager<Ship>
{
    public :
        Ship(void) : ObjectManager<Ship>()
        {
            cout << "Construct Ship at " << this << endl;
        }

        ~Ship(void)
        {
            cout << "Destroy Ship at " << this << endl;
        }

        friend ostream &operator<<(ostream    &out,const Ship &that)
        {
            out << "I am a ship";

            return out;
        }
};

/* A simple missile for testing */ 
class Missile : public ObjectManager<Missile>
{
    public :
        Missile(void) : ObjectManager<Missile>()
        {
            cout << "Construct Missile at " << this << endl;
        }

        ~Missile(void)
        {
            cout << "Destroy Missile at " << this << endl;
        }

        friend ostream &operator<<(ostream &out,const Missile &that)
        {
            out << "I am a missile";

            return out;
        }
};

/* A function suitable for the for_each function */ 
template <class T>
void show(T *it)
{
    cout << "Show: " << *it << " at " << it << endl;
}

int main(void)
{
    /* Create dummy planets for testing */ 
    Missile p1;
    Missile p2;

    /* Demonstrate Iterator */ 
    p1.for_each(show);

    /* Create dummy ships for testing */ 
    Ship s1;
    Ship s2;
    Ship s3;

    /* Demonstrate Iterator */ 
    s1.for_each(show);

    return 0;
}

具体来说,该列表通过继承机制有效地嵌入到每艘飞船中。一个人必须拥有一艘船才能访问船舶列表。必须拥有导弹才能访问导弹列表。感觉很尴尬。

我的问题归结为“有更好的方法吗?

  1. 自动创建对象容器
  2. 自动对象插入
  3. 无需列表中的对象即可访问容器。

我正在寻找更好的想法。 所有有用的条目都会获得赞成票。

谢谢

邪恶。

最佳答案

我认为这里的问题是你扩展了继承的概念。您拥有的是有效的代码并且可以工作,但是正如您所指出的,将容器类隐藏在子类的构造函数的幕后感觉不对。 (在我看来)这是因为导弹与其父类(容器)实际上没有任何共同点,当这是一种已经(正确地)抽象出来的设计模式时,您正在使用继承来提供此容器标准模板库。正如 John Zwinck 所建议的,工厂模式将提供一种更具表现力的方式来实现您想要的目标。

/* Container class to create and store various object groups */ 
template<class T>
class ObjectManager
{
public :
    ObjectManager() : nextAvailableIndex(0)
    {}

    virtual ~ObjectManager(void)
    {
        for (objectListIter = objectList.begin(); objectListIter != objectList.end(); ++objectListIter)
            delete *objectListIter;
    }

    T* ObjectManager::Create()
    {
        T* object = new Object(nextAvailableIndex++); 
        cout << "Constructed object " << object << endl;
        objectList.push_back(object);
    }

    void for_each(void (*function)(T *))
    {
        for (objectListIter = objectList.begin(); objectListIter != objectList.end(); ++objectListIter)
        {
            (*function)((T *) *objectListIter);
        }
    }

    int                nextAvailableIndex;
    list<T*>::iterator objectListIter;
    list<T*>           objectList;
};

int main(void)
{
    /* Create dummy planets for testing */ 
    ObjectManager<Missile> missileManager;
    Missile* p1 = missileManager.Create();

    /* Demonstrate Iterator */ 
    missileManager.for_each(show);

    /* Create dummy ships for testing */ 
    ObjectManager<Ship> shipManager;
    shipManager.Create(); 
    shipManager.Create(); 
    shipManager.Create(); 

    /* Demonstrate Iterator */ 
    shipManager.for_each(show); // will show three ships

    return 0;
}

我省略了导弹和船舶的类定义,因为我所做的唯一更改是构造函数中的一个整数作为唯一标识符。

关于c++ - 寻找更好的方法将静态列表集成到一组类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2442386/

相关文章:

javascript - es6 类将 this 传递给静态类函数

java - 深度优先搜索导致 StackOverFlowError

c++ - 递归函数破坏一般树c++

c++ - 递归代码的运行时错误

C++ 模板类从静态助手调用自己的构造函数

java - 计算完美数

c# - 我应该在 c# 中使用静态函数吗?

c++ - OpenCV:防止 HoughCircles 方法使用 Canny 检测

c++ - __asm__ gcc 调用内存地址

C++ 数组、函数和计数器