3rdParty/boost/1.78.0/libs/ptr_container/doc/examples.html
Some examples are given here and in the accompanying test files:
my_container.push_back( 0 ); // throws bad_ptr
my_container.replace( an_iterator, 0 ); // throws bad_ptr
my_container.insert( an_iterator, 0 ); // throws bad_ptr
std::auto_ptr<T> p( 0 );
my_container.push_back( p ); // throws bad_ptr
ptr_vector<X> pvec;
std::vector<X*> vec;
*vec.begin() = new X; // fine, memory leak
*pvec.begin() = new X; // compile time error
( *vec.begin() )->foo(); // call X::foo(), a bit clumsy
pvec.begin()->foo(); // no indirection needed
*vec.front() = X(); // overwrite first element
pvec.front() = X(); // no indirection needed
ptr_vector<T> vec1;
...
ptr_vector<T> vec2( vec1.clone() ); // deep copy objects of 'vec1' and use them to construct 'vec2', could be very expensive
vec2 = vec1.release(); // give up ownership of pointers in 'vec1' and pass the ownership to 'vec2', rather cheap
vec2.release(); // give up ownership; the objects will be deallocated if not assigned to another container
vec1 = vec2; // deep copy objects of 'vec2' and assign them to 'vec1', could be very expensive
ptr_vector<T> vec3( vec1 ); // deep copy objects of 'vec1', could be very expensive
// a class that has no normal copy semantics
class X : boost::noncopyable { public: X* clone() const; ... };
// this will be found by the library by argument dependent lookup (ADL)
X* new_clone( const X& x )
{ return x.clone(); }
// we can now use the interface that requires cloneability
ptr_vector<X> vec1, vec2;
...
vec2 = vec1.clone(); // 'clone()' requires cloning <g>
vec2.insert( vec2.end(), vec1.begin(), vec1.end() ); // inserting always means inserting clones
class X { ... }; // assume 'X' is Cloneable
X x; // and 'X' can be stack-allocated
ptr_list<X> list;
list.push_back( new_clone( x ) ); // insert a clone
list.push_back( new X ); // always give the pointer directly to the container to avoid leaks
list.push_back( &x ); // don't do this!!!
std::auto_ptr<X> p( new X );
list.push_back( p ); // give up ownership
BOOST_ASSERT( p.get() == 0 );
ptr_deque<T> deq;
typedef ptr_deque<T>::auto_type auto_type;
// ... fill the container somehow
auto_type ptr = deq.pop_back(); // remove back element from container and give up ownership
auto_type ptr2 = deq.release( deq.begin() + 2 ); // use an iterator to determine the element to release
ptr = deq.pop_front(); // supported for 'ptr_list' and 'ptr_deque'
deq.push_back( ptr.release() ); // give ownership back to the container
ptr_list<X> list; ptr_vector<X> vec;
...
//
// note: no cloning happens in these examples
//
list.transfer( list.begin(), vec.begin(), vec ); // make the first element of 'vec' the first element of 'list'
vec.transfer( vec.end(), list.begin(), list.end(), list ); // put all the lists element into the vector
We can also transfer objects from ptr_container<Derived> to ptr_container<Base> without any problems.
| incomplete_type_test.cpp: |
|---|
| simple_test.cpp: |
| --- |
| view_example.cpp: |
| --- |
| tree_test.cpp: |
| array_test.cpp: |
This example shows many of the most common features at work. The example provide lots of comments. The source code can also be found here.
// // Boost.Pointer Container // // Copyright Thorsten Ottosen 2003-2005. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE\_1\_0.txt or copy at // http://www.boost.org/LICENSE\_1\_0.txt) // // For more information, see http://www.boost.org/libs/ptr\_container/ // // // This example is intended to get you started. // Notice how the smart container // // 1. takes ownership of objects // 2. transfers ownership // 3. applies indirection to iterators // 4. clones objects from other smart containers // // // First we select which container to use. //#include\<boost/ptr\_container/ptr\_deque.hpp\>// // we need these later in the example //#include\<boost/assert.hpp\>#include\<string\>#include\<exception\>// // Then we define a small polymorphic class // hierarchy. //classanimal:boost::noncopyable{virtualstd::stringdo\_speak()const=0;std::stringname\_;protected:// // Animals cannot be copied... //animal(constanimal&r):name\_(r.name\_){}voidoperator=(constanimal&);private:// // ...but due to advances in genetics, we can clone them! //virtualanimal\*do\_clone()const=0;public:animal(conststd::string&name):name\_(name){}virtual~animal()throw(){}std::stringspeak()const{returndo\_speak();}std::stringname()const{returnname\_;}animal\*clone()const{returndo\_clone();}};// // An animal is still not Clonable. We need this last hook. // // Notice that we pass the animal by const reference // and return by pointer. //animal\*new\_clone(constanimal&a){returna.clone();}// // We do not need to define 'delete\_clone()' since // since the default is to call the default 'operator delete()'. //conststd::stringmuuuh="Muuuh!";conststd::stringoiink="Oiiink";classcow:publicanimal{virtualstd::stringdo\_speak()const{returnmuuuh;}virtualanimal\*do\_clone()const{returnnewcow(\*this);}public:cow(conststd::string&name):animal(name){}};classpig:publicanimal{virtualstd::stringdo\_speak()const{returnoiink;}virtualanimal\*do\_clone()const{returnnewpig(\*this);}public:pig(conststd::string&name):animal(name){}};// // Then we, of course, need a place to put all // those animals. //classfarm{// // This is where the smart containers are handy //typedefboost::ptr\_deque\<animal\>barn\_type;barn\_typebarn;// // A convenience typedef for the compiler-appropriate // smart pointer used to manage barns //typedef[_compatible-smart-ptr_](compatible_smart_ptr.html)\<barn\_type\>raii\_ptr;// // An error type //structfarm\_trouble:publicstd::exception{};public:// // We would like to make it possible to // iterate over the animals in the farm //typedefbarn\_type::iteratoranimal\_iterator;// // We also need to count the farm's size... //typedefbarn\_type::size\_typesize\_type;// // And we also want to transfer an animal // safely around. The easiest way to think // about '::auto\_type' is to imagine a simplified // 'std::auto\_ptr\<T\>' ... this means you can expect // // T\* operator-\>() // T\* release() // deleting destructor // // but not more. //typedefbarn\_type::auto\_typeanimal\_transport;// // Create an empty farm. //farm(){}// // We need a constructor that can make a new // farm by cloning a range of animals. //farm(animal\_iteratorbegin,animal\_iteratorend):// // Objects are always cloned before insertion // unless we explicitly add a pointer or // use 'release()'. Therefore we actually // clone all animals in the range //barn(begin,end){}// // ... so we need some other function too //animal\_iteratorbegin(){returnbarn.begin();}animal\_iteratorend(){returnbarn.end();}// // Here it is quite ok to have an 'animal\*' argument. // The smart container will handle all ownership // issues. //voidbuy\_animal(animal\*a){barn.push\_back(a);}// // The farm can also be in economical trouble and // therefore be in the need to sell animals. //animal\_transportsell\_animal(animal\_iteratorto\_sell){if(to\_sell==end())throwfarm\_trouble();// // Here we remove the animal from the barn, // but the animal is not deleted yet...it's // up to the buyer to decide what // to do with it. //returnbarn.release(to\_sell);}// // How big a farm do we have? //size\_typesize()const{returnbarn.size();}// // If things are bad, we might choose to sell all animals :-( //raii\_ptrsell\_farm(){returnbarn.release();}// // However, if things are good, we might buy somebody // else's farm :-) //voidbuy\_farm(raii\_ptrother){// // This line inserts all the animals from 'other' // and is guaranteed either to succeed or to have no // effect //barn.transfer(barn.end(),// insert new animals at the end\*other);// we want to transfer all animals, // so we use the whole container as argument // // You might think you would have to do // // other.release(); // // but '\*other' is empty and can go out of scope as it wants //BOOST\_ASSERT(other-\>empty());}};// class 'farm'.intmain(){// // First we make a farm //farmanimal\_farm;BOOST\_ASSERT(animal\_farm.size()==0u);animal\_farm.buy\_animal(newpig("Betty"));animal\_farm.buy\_animal(newpig("Benny"));animal\_farm.buy\_animal(newpig("Jeltzin"));animal\_farm.buy\_animal(newcow("Hanz"));animal\_farm.buy\_animal(newcow("Mary"));animal\_farm.buy\_animal(newcow("Frederik"));BOOST\_ASSERT(animal\_farm.size()==6u);// // Then we make another farm...it will actually contain // a clone of the other farm. //farmnew\_farm(animal\_farm.begin(),animal\_farm.end());BOOST\_ASSERT(new\_farm.size()==6u);// // Is it really clones in the new farm? //BOOST\_ASSERT(new\_farm.begin()-\>name()=="Betty");// // Then we search for an animal, Mary (the Crown Princess of Denmark), // because we would like to buy her ... //typedeffarm::animal\_iteratoriterator;iteratorto\_sell;for(iteratori=animal\_farm.begin(),end=animal\_farm.end();i!=end;++i){if(i-\>name()=="Mary"){to\_sell=i;break;}}farm::animal\_transportmary=animal\_farm.sell\_animal(to\_sell);if(mary-\>speak()==muuuh)// // Great, Mary is a cow, and she may live longer //new\_farm.buy\_animal(mary.release());else// // Then the animal would be destroyed (!) // when we go out of scope. //;// // Now we can observe some changes to the two farms... //BOOST\_ASSERT(animal\_farm.size()==5u);BOOST\_ASSERT(new\_farm.size()==7u);// // The new farm has however underestimated how much // it cost to feed Mary and its owner is forced to sell the farm... //animal\_farm.buy\_farm(new\_farm.sell\_farm());BOOST\_ASSERT(new\_farm.size()==0u);BOOST\_ASSERT(animal\_farm.size()==12u);}
Navigate:
| Copyright: | Thorsten Ottosen 2004-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt). |