在某种情况下,我有std::vector
指向ClassA
的指针。另一个类ClassB
继承自ClassA
。在某些时候我知道这个向量only
包含指向ClassB实例的指针。我使用foreach loop
迭代向量,然后将cast
对象转换为ClassB。
目前看起来与此类似:
Class ClassA
{
}
Class ClassB : public ClassA
{
public:
void DoSomething();
}
std::vector<ClassA*> vecA;
void iterate()
{
for(ClassA* obj : vecA)
{
((ClassB*)obj)->DoSomething();
}
}
我想知道我是否可以在foreach循环中直接转换对象。这会更短,并且每次我想要使用它时都不需要我施放物体。我正在寻找看起来像这样的东西:
void iterate()
{
for((ClassB*)ClassA* obj : vecA)
{
obj->DoSomething();
}
}
这可能吗?如果不是,那么什么是一种简单的方法来节省&#39;演员,如果我想多次使用演出的对象?
提前致谢。
答案 0 :(得分:3)
void iterate() {
for(ClassA* obj_ : vecA) {
Assert(dynamic_cast<ClassB*>(obj_)); // debug build sanity check
auto* obj = static_cast<ClassB*>(obj_);
obj->DoSomething();
}
}
答案 1 :(得分:2)
容器包装器怎么样?我们先来看一下用法:
void iterate()
{
for (ClassB* obj : cast_range<ClassB*>(vecA))
{
obj->DoSomething();
}
}
这是一个可能的实现:
template<typename Target, typename Underlying>
struct cast_iterator_t
{
Underlying it;
Target operator*() const
{
return (Target) *it;
}
bool operator==(cast_iterator_t that) const
{
return it == that.it;
}
bool operator!=(cast_iterator_t that) const
{
return it != that.it;
}
cast_iterator_t& operator++()
{
++it;
return *this;
}
cast_iterator_t operator++(int)
{
cast_iterator_t old(*this);
++*this;
return old;
}
};
template<typename Target, typename Underlying>
cast_iterator_t<Target, Underlying> cast_iterator(Underlying it)
{
return {it};
}
template<typename Target, typename Range>
struct cast_range_t
{
Range& range;
decltype(cast_iterator<Target>(std::begin(range))) begin()
{
return cast_iterator<Target>(std::begin(range));
}
decltype(cast_iterator<Target>(std::end(range))) end()
{
return cast_iterator<Target>(std::end(range));
}
};
template<typename Target, typename Range>
cast_range_t<Target, Range> cast_range(Range& range)
{
return {range};
}