列表容器 - 使用不相关的类型存储和删除

时间:2012-12-16 01:50:38

标签: c++

编辑:

我选择重写我的整个问题并逐步完成。

因此我希望在std :: list中存储类型(如下面的ObjectA和ObjectB),其中这些类型必须都具有返回预期类型的​​成员属性(如本示例中的int const *):

class ObjectA
{

public:

    int const* GetItem () {return mpItem;} const;

private:

    int*        mpItem;
    ObjectC     mrObjectC;

}; // class



class ObjectB
{

public:

    int const* GetItem () {return &mrItem;} const;

private:

    int         mrItem;
    ObjectD     mrObjectD;

}; // class

所以现在上面的两个对象需要在std :: list中,如:

ObjectA         nrA;
ObjectB         nrB;

std::list<###   const*> nrRender;

nrRender.push_back (nrA); // comes down to storing ObjectA and ObjectB
nrRender.push_back (nrB); // inside the same list

完成所有这些后。子例程迭代std :: list并发送数据以进行进一步处理,如下所示:

std::list<###   const*> nrRender::const_iterator niObject;
for (niObject = nrRender.begin(); niObject != nrRender.end(); ++niObject) {

    this -> Display ((*niObject).GetItem ());

}

最后我也想这样做:

nrRender.remove(nrA);
nrRender.remove(nrB);

2 个答案:

答案 0 :(得分:0)

如果我正确理解你的代码,nrZ对象可以检查通过HooksInto方法传递给它的任何内容,并保留在该参数中找到的内部对象的引用。

例如,如果对象nrB包含对象iB1iB2nrZ可以通过检查nrB找到它们并保留对它们的引用。< / p>

nrRender.push_back(nrZ)调用让nRender获取这些引用并存储它们以供进一步处理;但是,如果调用nrRender.remove(nrB),则必须从nrRender对象中删除这些引用。

我将假设代码中提到的list模板实际上是std::list

因此,nrRender只能存储TypeZ类型的值。这实际上是代码中的一个问题。如果您希望nrRender跟踪TypeATypeZ值,则必须将其列为最常规类型的列表:TypeA。但是,一旦在列表中按下某个值,就会忘记其完整类型,如下所示:

  list<TypeA *> nrRender;
  TypeB nrB;      
  TypeA *ptr;

  nrRender.push_back(&nrB);
  ptr = nrRender.pop_back(); // here we're getting back nrB, 
                             // but now it's a (TypeA *) value

此外,如果您不使列表成为实例指针的列表,那么您将无法保留对传入的对象的引用。

接下来,您想要的功能不可用。 nrZ::HooksInto方法建议您使用合成构建对象,当您需要通过继承构建对象时,list<TypeA>::remove方法可以按要求工作。

如果list不是std::list,但是您希望使用所需的功能实现某个模板,我想这可以做到,但我没有看到制作它的重点模板。

 class render_list {

   public:
     /* ... */
     void push_back(const TypeZ &t){
         // get the inner references within t
         // store them in this instance
     }
     void remove(const TypeA &t){
         // remove t
     }
     // overload remove if necessary to handle TypeB peculiarity
     void remove(const TypeB &t){
         // remove t
     }
     // etc.
     void remove(const TypeA &t){
         // remove t
     }
 };

请注意,如果没有关于您正在努力实现的目标的详细信息,很难提供更好的指导。

答案 1 :(得分:0)

在与编译器争夺半天后,这里是解决方案(虚拟接口和基类一起工作):

class TypeA
{

public:

    virtual int GetCount () = 0; // The notation =0 simply indicates the Virtual function is a pure virtual function as it has no body

};



class TypeB : public TypeA
{

    string      GetTitle ();

public:

    string      mrTitle;

};



class TypeC : public TypeB
{

public:

    int GetCount () {return 5;}

};



class TypeD : public TypeB
{

public:

    int GetCount () {return 8;}

};

测试解决方案:

        TypeC           nrC;
        TypeD           nrD;
        list<TypeB*>    nrRender;

        nrRender.push_back(&nrC);
        nrC.GetCount();

        nrRender.push_back(&nrD);
        nrC.GetCount();

        cout << endl << "Ca: " << &nrC;
        cout << endl << "Da: " << &nrD;

        cout << endl << "SizeA: " << nrRender.size();

        list<TypeB*>::iterator niItem;
        for (niItem = nrRender.begin(); niItem != nrRender.end(); ++niItem) {

            cout << endl << "Adress: " << (*niItem);
            cout << endl << "Counts: " << (*niItem) -> GetCount();

        }

        nrRender.remove(&nrD);

        cout << endl << "SizeB: " << nrRender.size();

        for (niItem = nrRender.begin(); niItem != nrRender.end(); ++niItem) {

            cout << endl << "Adress: " << (*niItem);
            cout << endl << "Counts: " << (*niItem) -> GetCount();

        }

我希望这会对某人有所帮助。