Pregunta

I have a question about a run time checking operation. If a class contains a vector of objects deriving from BPAbstract (BPAbstract being purely virtual) like:

typedef std::shared_ptr<BPAbstract> Ptr;
std::vector<BPAbstract::Ptr> objects_;

Now lets say that I want to group objects of a specific type in a vector.

template<class T>
void
GetObjectsByType( std::vector<typename T::Ptr> list ) const
{
    for( BPAbstract::Ptr i : objects_ )
    {
        // ???? ....
    }
}

What would be the best implementation ? One solution would be to try to cast i into the type T and if the result is non null then I can add it to the list list. I am pretty sure someone knows a better solution...

A suggestion of a better implementation of the idea would also be acceptable !

¿Fue útil?

Solución

You need dynamic pointer cast Your question is already answered

template<class T>
void
GetObjectsByType( std::vector<typename T::Ptr> list ) const
{
    for( BPAbstract::Ptr i : objects_ )
    {
        T::Ptr candidate = std::dynamic_pointer_cast<T>(i);
        if (candidate)
            list.add(candidate);
    }
}

Otros consejos

Sorry about the C++0X Syntax, but dynamic cast is an option:

class Ai
{
public:
  virtual void a() = 0;
};

class Bi : public Ai
{
public:
  virtual void b() = 0;
};

class A : public Ai
{
public:
  virtual void a() override {printf("Aa\n");}
};

class B : public Bi
{
public:
  virtual void a() override {printf("Ba\n");}
  virtual void b() override {printf("Bb\n");}
};


int _tmain(int argc, _TCHAR* argv[])
{
  typedef std::shared_ptr<Ai> Ptr;
  std::vector<Ptr> list;
  list.push_back(Ptr(new A()));
  list.push_back(Ptr(new B()));

  for (auto i = list.begin(); i != list.end(); ++i)
  {
    (*i)->a();
    auto b = std::dynamic_pointer_cast<Bi>(*i);

    if (b)
    {
      b->b();
    }
    //or, equally valid without additional shared_ptr overhead:

    auto bptr = dynamic_cast<Bi*>(i->get());
    if (bptr )
    {
      bptr->b();
    }
  }

}

However, Dynamic Cast is slow. You'd really want to do a static cast (by exposing a member that says Hey, I am a Bi (not recommended, as it is a giant pain in the but to maintain) ), or use polymorphism to select behavior (by making b() a function in Ai, and have it do nothing in the classes you want it to do nothing on).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top