|
Boost Users : |
From: Björn Karlsson (bjorn.karlsson_at_[hidden])
Date: 2001-12-11 04:20:42
> From: rz0 [mailto:rz0_at_[hidden]]
> Hi Bjorn
>
> Thank you very much for the reply.
>
> Unfortunately these classes are provided to me and as part of the
> requirements, I must be able to work with them. In re-thinking the
> problem, it seems that I'm in desperate need of a polymorphic
> container - i.e.:
>
>
> Does boost have any polymorphic containers?
>
> Thanks very much in advance.
>
>
I don't think that polymorphism is the cure - you'll always need to downcast
the pointer as the signatures differ. However, there is support in Boost for
what you're trying to do - through boost::any. Like I said before, the
solution will not be very clean, but it will work.
The code snippet below seems to do what you're asking for:
#include <iostream>
#include <algorithm>
#include <vector>
#include <Boost\Any.hpp>
class A
{
public:
virtual void func1() { std::cout << "A::func1()\n"; };
};
class B : public A
{
public:
void func1() { std::cout << "B::func1()\n"; };
void funcB() { std::cout << "B::funcB()\n"; };
};
class C : public A
{
public:
void func1() { std::cout << "C::func1()\n"; };
void funcC() { std::cout << "C::funcC()\n"; };
};
typedef std::vector<boost::any> AnyVector;
void DoStuffWithAny(boost::any& a)
{
// Try with a B
if ( B* pB = boost::any_cast<B>(&a) )
{
pB->func1();
pB->funcB();
}
// Try with a C
else if ( C* pC = boost::any_cast<C>(&a) )
{
pC->func1();
pC->funcC();
}
// Try with an A
else if ( A* pA = boost::any_cast<A>(&a) )
{
pA->func1();
}
}
void DoStuffWithAnyPointer(boost::any& a)
{
// Try with a B
if ( B** ppB = boost::any_cast<B*>(&a) )
{
(*ppB)->func1();
(*ppB)->funcB();
}
// Try with a C
else if ( C** ppC = boost::any_cast<C*>(&a) )
{
(*ppC)->func1();
(*ppC)->funcC();
}
// Try with an A
else if ( A** ppA = boost::any_cast<A*>(&a) )
{
(*ppA)->func1();
}
}
int main(int argc, char* argv[])
{
AnyVector aVector;
A a;
B b;
C c;
aVector.push_back(a);
aVector.push_back(b);
aVector.push_back(c);
// Do interesting things
std::for_each(aVector.begin(), aVector.end(), DoStuffWithAny);
AnyVector anotherVector;
anotherVector.push_back(new A);
anotherVector.push_back(new B);
anotherVector.push_back(new C);
// Do interesting things
std::for_each(anotherVector.begin(), anotherVector.end(),
DoStuffWithAnyPointer);
return 0;
}
Another approach would be to provide adapters, but I'm guessing that
wouldn't be worth the trouble.
HTH,
Bjorn Karlsson
[Non-text portions of this message have been removed]
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net