#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/shared_array.hpp>
#include <memory>
#include <vector>
#define KNOTE(fmt, args...) ::printf(fmt "\n", ##args)
// Vector of unique_ptr should be your default choice
typedef std::vector<std::unique_ptr<TClass>> TClassUniqueVector;
// Vector of shared_ptr should be used if TClass is shared to others
typedef std::vector<std::shared_ptr<TClass>> TClassSharedVector;
// ptr_vector may has best performance
typedef boost::ptr_vector<TClass> TClassPtrVector;
// unique_ptr can take a fix-sized array of objects
typedef std::unique_ptr<TClass[]> TClassUniqueArray;
// shared_array for a fix-sized array of objects
typedef boost::shared_array<TClass> TClassBoostSharedArray;
void Foo(const std::unique_ptr<TClass>& c)
{
c->IntValue++;
}
void Foo(const std::shared_ptr<TClass>& c)
{
c->IntValue++;
}
void TestSmartPtrMiscs()
{
TClassUniqueVector cv;
auto uc(std::unique_ptr<TClass>(new TClass(1)));
cv.push_back(std::move(uc));
cv.push_back(std::unique_ptr<TClass>(new TClass(2)));
Foo(cv.back());
TClassSharedVector sv;
auto sc = std::make_shared<TClass>(100);
sv.push_back(sc);
sv.push_back(std::make_shared<TClass>(101));
Foo(sv.back());
}
void TestPtrVector()
{
TClassPtrVector pv;
pv.push_back(new TClass(1));
TClass* c = new TClass(2);
pv.push_back(c);
}
void TestSmartPtrWithArray()
{
{
KNOTE("\nstd::unique_ptr with array");
// Usage of unique_ptr for array
std::unique_ptr<TClass[]> ua(new TClass[5]{1, 2, 3, 4, 5});
KNOTE("Access with []: %d", ua[3].IntValue);
}
{
KNOTE("\nboost::scoped_ptr with array is not supported");
// Compile error
//boost::scoped_ptr<TClass[]> s(new TClass[5]{6,7,8,9,10});
}
{
KNOTE("\nstd::shared_ptr with array is not supported");
// Compile error
//std::shared_ptr<TClass[]> a(new TClass[5]{6, 7, 8, 9, 10});
}
{
KNOTE("\nstd::shared_ptr with array shall come with custom deleter");
// Usage of shared_ptr for array
// Note you must supply a correct deleter for array
std::shared_ptr<TClass> sa2(new TClass[5]{6, 7, 8, 9, 10},
std::default_delete<TClass[]>());
KNOTE("Access with .get()[]: %d", (sa2.get())[3].IntValue);
}
{
KNOTE("\nboost::shared_ptr with array is supported");
boost::shared_ptr<TClass[]> a(new TClass[5]{100, 101, 102});
KNOTE("Access with []: %d", a[3].IntValue);
}
{
KNOTE("\nboost::shared_array is an alternative");
// It also can be done by boost::shared_array
boost::shared_array<TClass> bsa(new TClass[5]{100, 101, 102});
KNOTE("Access with []: %d", bsa[3].IntValue);
}
{
KNOTE("\nBoth std and boost shared_ptr<T> with array T[] "
"cause segment fault");
// std::shared_ptr<TClass> a(new TClass[5]); // Crash
// boost::shared_ptr<TClass> b(new TClass[5]); // Crash
}
}
int main()
{
TestSmartPtrMiscs();
TestPtrVector();
TestSmartPtrWithArray();
return 0;
}