The following example assumes the declaration from the previous boost::any(1) post:
int main()
{
typedef std::vector<boost::any> MixedContainer_t;
MixedContainer_t mixedContainer;
A* aPtr1 = new A(2);
A* aPtr2 = new A(3);
mixedContainer.push_back(aPtr1);
mixedContainer.push_back(aPtr2);
//would not work. What is stored at front() is a pointer to A
//and not an object of type A.
if(A* a = boost::any_cast<A> (&mixedContainer.front()))
a->print();
//we can even confirm it by testing the types
if(typeid(A*) == mixedContainer.back().type())
{
std::cout << "object at front() is a pointer to A" << std::endl;
}
//to get a pointer to it, we need to retrieve a A**, and pass
//the type of object we think stored at front as A*
if(A** a = boost::any_cast<A*> (&mixedContainer.front()))
{
std::cout << "pointer-> ";
(*a)->print();
}
}
Storing pointers in boost::any is problematic, because boost::any stores only a value of the pointer, and when the boost::any is destroyed, the only memory that is released is that occupied by the pointer, and not the memory it points to. That is, delete or delete[] is not called. What to do? Use smart pointers. As with standard containers, avoid using auto_ptr because of its 'weird' copy semantics.
#include <iostream>
#include <vector>
#include <boost/any.hpp>
#include <boost/shared_ptr.hpp>
class A
{
int value_;
public:
A(int value) : value_(value) {}
void print() const {std::cout << "A's value: " << value_ << std::endl;}
~A() {std::cout << "A(" << value_ <<") destructor" << std::endl; }
};
class B
{
int value_;
public:
B(int value) : value_(value) {}
void print() const {std::cout << "B's value: " << value_ << std::endl;}
~B() {std::cout << "B(" << value_ <<") destructor" << std::endl; }
};
int main()
{
typedef std::vector<boost::any> MixedContainer_t;
MixedContainer_t mixedContainer;
boost::shared_ptr<A> aPtr0(new A(1));
A* aPtr1 = new A(2);
A* aPtr2 = new A(3);
mixedContainer.push_back(aPtr0);
mixedContainer.push_back(aPtr1);
mixedContainer.push_back(aPtr2);
//and to retrieve the value from shared Ptr is simple
try
{
boost::shared_ptr<A> ptr = boost::any_cast<boost::shared_ptr<A> > (mixedContainer.front());
ptr->print();
}
catch(boost::bad_any_cast& bac)
{
bac.what();
}
//only the destructor of the A pointed to by shared_ptr is printed.
}
No comments :
Post a Comment