我想创建一个结构,我可以“迭代”一个类的所有对象(可能还有所有派生类的对象,但这会被忽略)。但是它不应该迭代“父”类:
我们假设我有以下系统:
A 是基类
C 和 D 来源于此 E 源自 C
现在,如果我“迭代D”,我想迭代D,但不是a。然而,在同一个我希望能够“迭代C” - 这将让我迭代所有“C”对象 - 也可能迭代所有E对象(虽然这是不必要的,它也不错)
我怎样才能实现这一目标?
我尝试了一个名为“myObjects”的静态变量来链接所有对象。但是我很快就注意到我不能在派生类中重载静态变量。 (因此C的“myObjects”与A的“myObjects”相同,或者D)
答案 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
添加到容器中。
这样,每个类中的静态容器只包含那些没有子类的类的实例。可以在每个子类中重写基类中用于访问实例列表的虚函数,以访问特定于类的容器。
破坏和复制结构必须足够智能,以便正确维护容器。