【问题标题】:List container - storing and removal using unrelated types列表容器 - 使用不相关类型存储和删除
【发布时间】:2012-12-03 14:08:18
【问题描述】:

编辑:

我选择重新编写我的整个问题,并逐步使其更加完善。

所以我想在 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);

标签: c++


【解决方案1】:

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

例如,如果对象nrB 包含对象iB1iB2,则nrZ 可以通过检查nrB 找到它们并保留对它们的引用。

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&lt;TypeA&gt;::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
     }
 };

请注意,如果不详细说明您想要达到的目标,很难提供更好的指导。

【讨论】:

  • 感谢您的宝贵时间,您的假设是正确的……我大部分时间都在寻找答案,看来我确实有设计感。我一直在研究纯虚拟界面,但目前还不确定它们是否是我的答案……这是一个简单的想法,但很难解释,我将添加更多代码来尝试解释我很快需要什么。
【解决方案2】:

在与编译器斗争了半天之后,这里是解决方案(虚拟接口和基类合二为一):

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();

        }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    相关资源
    最近更新 更多