|
// boostspsample.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "boost/smart_ptr.hpp"
#include <vector>
// ==================================================================
// CSample::
// ------------------------------------------------------------------
///
/// A class that echoes construction / destruction to the console.
/// This will help us seeing what happens
///
class CSample
{
protected:
int m_n; ///< helps identify different instances
static int NewInstanceID;
public:
CSample() { m_n = ++NewInstanceID; printf("constructing CSample(%i)\n", m_n); }
~CSample() { printf("destroying CSample(%i)\n", m_n); }
bool Query() { printf("CSample(%i)::Query - returning true \n", m_n); return true; }
void Use() { printf("CSample(%i)::Use\n", m_n); }
};
typedef boost::shared_ptr<CSample> CSamplePtr;
int CSample::NewInstanceID = 0;
// ==================================================================
// Sample1_ScopedPtr
// ------------------------------------------------------------------
///
/// Sample: scoped_ptr - automatic destruction on exit
///
void Sample1_ScopedPtr()
{
boost::scoped_ptr<CSample> pSample(new CSample);
if (!pSample->Query() )
return;
pSample->Use();
}
// ==================================================================
// Sample1_Plain
// ------------------------------------------------------------------
///
/// Sample: PLain Pointer counterpart for Sample1_ScopedPtr
///
void Sample1_Plain()
{
CSample * pSample = new CSample;
if (!pSample->Query() )
{
delete pSample;
return;
}
pSample->Use();
delete pSample;
}
// ==================================================================
// boost::Sample2_Shared
// ------------------------------------------------------------------
///
/// demonstrates basic use of shared_ptr
///
void Sample2_Shared()
{
// (A) create a new CSample instance with one reference
boost::shared_ptr<CSample> mySample(new CSample);
printf("The Sample now has %i references\n", mySample.use_count()); // should be 1
// (B) assign a second pointer to it:
boost::shared_ptr<CSample> mySample2 = mySample; // should be 2 refs by now
printf("The Sample now has %i references\n", mySample.use_count());
// (C) set the first pointer to NULL
mySample.reset();
printf("The Sample now has %i references\n", mySample2.use_count()); // 1
// the object allocated in (1) is deleted automatically when mySample2 goes out of scope
}
// ==================================================================
// boost::Sample3_Container
// ------------------------------------------------------------------
///
/// demonstrates basic use of shared_ptr
///
void Sample3_Container()
{
typedef boost::shared_ptr<CSample> CSamplePtr;
// (A) create a container of CSample pointers:
std::vector<CSamplePtr> vec;
// (B) add two elements
printf("adding three elements to a vector...\n");
vec.push_back(CSamplePtr(new CSample));
vec.push_back(CSamplePtr(new CSample));
vec.push_back(CSamplePtr(new CSample));
// (C) "keep" a pointer to the second:
printf("keeping a reference to the second...\n");
CSamplePtr anElement = vec[1];
// (D) destroy the vector:
printf("destroying the vector releases it's elements...\n");
vec.clear();
// (E) the second element still exists
printf("referenced elements still exist, however...\n");
anElement->Use();
printf("done. cleanup is automatic\n");
// (F) anElement goes out of scope...
}
// ==================================================================
// boost::Sample4_NeedForWeak
// ------------------------------------------------------------------
struct CDad;
struct CChild;
typedef boost::shared_ptr<CDad> CDadPtr;
typedef boost::shared_ptr<CChild> CChildPtr;
struct CDad : public CSample
{
CSamplePtr myBoy;
void SetBeer() { printf("Dad(%i) happy!\n", m_n); }
};
struct CChild : public CSample
{
CDadPtr myDad;
void BringBeer() { myDad->SetBeer(); }
};
///
/// deliberately creates a circular reference, and resolves it manually
///
void Sample4_NeedForWeak()
{
// a "thing" that holds a smart pointer to another "thing":
CDadPtr parent(new CDad);
CChildPtr child(new CChild);
// deliberately create a circular reference:
parent->myBoy = child;
child->myDad = parent;
// resetting one ptr...
child.reset();
// parent.reset() - this would leak both objects!
// we resolve this manually:
parent->myBoy.reset();
parent.reset();
}
// ==================================================================
// boost::Sample5_Using weak_ptr
// ------------------------------------------------------------------
struct CBetterChild : public CSample
{
boost::weak_ptr<CDad> myDad;
void BringBeer()
{
CDadPtr strongDad = myDad.lock(); // request a strong pointer to the parent object
if (strongDad) // object still exists?
{
strongDad->SetBeer();
}
else
{
printf("Child(%i): Out of Dad\n", m_n);
}
}
};
typedef boost::shared_ptr<CBetterChild> CBetterChildPtr;
void Sample5_Using_weak_ptr()
{
printf("Parent: ");
CDadPtr parent(new CDad);
printf("Child: ");
CBetterChildPtr child(new CBetterChild);
parent->myBoy = child;
child->myDad = parent;
// ...
printf("Bring beer to existing dad...\n");
child->BringBeer();
printf("set dad to NULL\n");
parent.reset();
printf("now, we cannot bring this dad beer anymore..\n");
child->BringBeer();
}
extern "C" int getch();
int main(int argc, char* argv[])
{
printf("\n *** Sample 1: using plain pointers\n");
Sample1_Plain();
printf("\n *** Sample 1: using scoped_ptr\n");
Sample1_ScopedPtr();
printf("\n *** Sample 2: basic shared_ptr\n");
Sample2_Shared();
printf("\n *** Sample 3: vector of shared_ptr\n");
Sample3_Container();
printf("\n *** Sample 4: vector of shared_ptr\n");
Sample4_NeedForWeak();
printf("\n *** Sample 5: using weak_ptr\n");
Sample5_Using_weak_ptr();
getch();
return 0;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Peter is tired of being called "Mr. Chen", even so certain individuals insist on it. No, he's not chinese.
Peter has seen lots of boxes you youngsters wouldn't even accept as calculators. He is proud of having visited the insides of a 16 Bit Machine.
In his spare time he ponders new ways of turning groceries into biohazards, or tries to coax South American officials to add some stamps to his passport.
Beyond these trivialities Peter works for
Klippel[
^], a small german company that wants to make mankind happier by selling them novel loudspeaker measurement equipment.
Where are you from?[^]
Please, if you are using one of my articles for anything, just leave me a comment. Seeing that this stuff is actually useful to someone is what keeps me posting and updating them.
Should you happen to not like it, tell me, too