迭代一个类的所有对象(但不是该类的父类 - C ++)

时间:2010-11-17 20:30:13

标签: c++ inheritance static-variables

我想创建一个结构,我可以“迭代”一个类的所有对象(可能还有所有派生类的对象,但这会被忽略)。但是它不应该迭代“父”类:

我们假设我有以下系统:

  

A 是基类
   C D 来源于此    E 源自 C

现在,如果我“迭代D”,我想迭代D,但不是a。然而,在同一个我希望能够“迭代C” - 这将让我迭代所有“C”对象 - 也可能迭代所有E对象(虽然这是不必要的,它也不错)

我怎样才能实现这一目标?

我尝试了一个名为“myObjects”的静态变量来链接所有对象。但是我很快就注意到我不能在派生类中重载静态变量。 (因此C的“myObjects”与A的“myObjects”相同,或者D)

4 个答案:

答案 0 :(得分:2)

int count = std::accumulate(x.begin(), x.end(), 0, [](int current_count, A* a)
                           {
                             if (dynamic_cast<D*>(a)) ++current_count;
                             return current_count;
                           });

应该这样做。

如果你没有lambda,你当然必须将所有这些都放在一个真正的功能中。

count_if版本:

auto count = std::count_if(x.begin(), x.end(), [](A* a) { return dynamic_cast<D*>(a) != 0; });

如果您没有自动,则需要声明类型:std::iterator_traits<X_type::iterator>::difference_type

您可以尝试分配给int但是,如果我正确阅读,difference_type可以是任何整数类型,并可能导致警告/溢出。令人怀疑的是,一个static_cast会解决它。

如果你只是想在D *上调用一些操作,那么使用foreach和上面的方法来实现。您可能想要查看各种访问者模式。

答案 1 :(得分:0)

  

但是我很快注意到我不能在派生类中重载静态变量

当然不是,你不能重载任何变量。重载仅适用于函数,因为它们的签名可能不同。

你可以让一个构造函数在基类中使用bool来指示是否要将对象放入“已知对象列表”中并提供false作为默认值。然后只在派生类中调用带有true的构造函数,其实际应该将对象插入到列表中。

但是,可能有一个更好的解决方案可以放弃继承以支持政策。

答案 2 :(得分:0)

在A和它的孩子之间建立一个抽象类中介。将静态对象放在那里。然后从中派生类而不是直接从A派生类。例如:

class A {};


 // make this class abstract, or not
class subA : A {
    static std::list<subA *> list_;
};

class C : subA {};
class D : subA {};

答案 3 :(得分:0)

您可以通过包含该类的static个实例容器的每个类来完成此工作,该容器没有子类。

然后在构造时,每个类提供一个protected构造函数供子类使用,一个public构造函数用于非继承实例创建。每个类中的protected构造函数不会将this添加到实例容器中,而public构造函数会将this添加到容器中。

这样,每个类中的静态容器只包含那些没有子类的类的实例。可以在每个子类中重写基类中用于访问实例列表的虚函数,以访问特定于类的容器。

破坏和复制结构必须足够智能,以便正确维护容器。