LipingPtr C++ Template Class

 

The last source code update date: 08/30/2008
Web: www.lipingshare.com/LipingPtr
Email: LipingShare@gmail.com
Title:       LipingPtr C++ Template Class

Author:      Liping Dai

Email:       lipingsharemail@gmail.com

Language:    C++

Platform:    Win32, Win64, Linux 2.6

Technology:  C++, STL

Description: A C++ Smart Pointer Template Class Implementation

Section      C++ 

 

·         Download LipingPtr - 4.41 KB

·         Download LipingPtrTest - 13.89 KB

 

Table of Content

1.    Overview.. 2

1.1        Design Principle. 2

1.2        Thread-safe. 2

1.3        Support Custom De-Allocator 2

1.4        LipingArray. 2

1.5        BinData. 2

1.6        FilePtr 2

2.    Build LipingPtrTest Demo Project 2

2.1       Visual Studio 2005 Build. 2

2.2       Linux Build. 2

3.    Basic Usage. 3

3.1        Manage Object Pointer 3

3.2        Manage Object Array Pointer 3

3.2.1          Manage LipingPtrTest array by using LipingArray. 3

3.2.2          Manage char array by using LipingArray. 3

3.2.3          Manage unsigned char array by BinData. 3

3.2.4          Explicitly Use De-Allocator 4

3.2.5          Use LipingPtr with STL Vector 4

3.2.6          Use LipingPtr with STL Map. 5

3.3        Attach, Detach, and ReleaseData Functions. 7

3.4        Multi Dimensional Array Usage. 9

3.5        Supported Operators. 11

4.    Use LipingPtr Manage Other Pointers Sample. 13

4.1        Define a De-Allocator for OpenCV IplImage. 13

4.2        Use Defined Type to Return CvImagePtr Pointer 13

5. Use Base Class LipingPtr Manage Descendent Class Pointers. 13

5.1 Description. 13

5.2 Sample Code. 13

6.    Demo Class Definition. 14

6.1        Data Structures Used in Sample Code. 14

6.2        LipingPtrTest.h. 14

6.3        LipingPtrTest.cpp. 15

7.    Copyright and Permission. 16

8.    Update History. 16

 

1.    Overview

LipingPtr is a reference counted C++ Smart Pointer Template Class. It keeps track of the pointer usage and deletes it when the reference counter reaches 0. LipingPtr tried to combine most frequently used features of smart pointers together and represent them in a single file. Keep the usage simple is the main goal of LipingPtr. It may not include all the functionalities smart pointers cold have; but it tried hard to keep the usages simple.

1.1               Design Principle

High performance and easy to use are the major design considerations for LipingPtr.

1.2       Thread-safe

LipingPtr uses “Critical Section” in Win32 and Win64 for the shared data protection. It uses “pthread_mutex_t” for the protection in Linux.

1.3               Support Custom De-Allocator

By default, LipingPtr uses "delete" to release the allocated memory. The user can also define own De-Allocator to release the resources.

1.4        LipingArray

LipingArray is a class that derived from LipingPtr. It is designed for managing multi dimensional arrays. It can also save and load array content to/from files. LipingArray issues "delete []" to release allocated memory at the end.

1.5        BinData

BinData is a predefined data type which uses LipingArray to manage binary data.

1.6        FilePtr

It is a predefined data type which uses LipingPtr to keep track of FILE pointer. It is also been used in LipingArray SaveFile() and LoadFile(). FilePtr closes the opened file(s) when the FilePtr goes out of the scope.

2.    Build LipingPtrTest Demo Project

2.1       Visual Studio 2005 Build

LipingPtrTest.sln is the solution file for Visual Studio 2005. You can select build for Win32 or Win64 platforms.

2.2       Linux Build

You can use the makefile to build LipingPtrTest on Linux.

3.    Basic Usage

3.1              Manage Object Pointer

Create a new class instance and use LipingPtr to manage it.

Sample Code:

{

       LipingPtr<LipingPtrTest> p1(new LipingPtrTest);

       p1->Hello(true);

}

The LipingPtrTest instance p1 will be released when it out of the code section.

Note: LipingPtrTest definition is attached at the end of this file.

3.2              Manage Object Array Pointer

3.2.1          Manage LipingPtrTest array by using LipingArray

This is the sample code that creates an array of LipingPtrTest and calls the Hello method for each array element.

{

       int arraySize = 3;

       LipingArray<LipingPtrTest> cp(new LipingPtrTest[arraySize]);

       for (int i = 0; i < arraySize; i++)

       {

              if (printit) cp.RawPtr()[i].Hello(printit);

       }

}

3.2.2          Manage char array by using LipingArray

{

       const int arraySize = 1024*10;

       LipingArray<char> cp(new char[arraySize]);

       strcpy_s(cp.RawPtr(), arraySize, "Hello LipingArray");

       if (printit) printf("LipingPtr<char> = %s\n", cp.RawPtr());

}

3.2.3          Manage unsigned char array by BinData

This sample shows how to use BinData to manage the unsigned char array and Save/Load data to/from files.

{

       const int arraySize = 256;

       BinData bin(arraySize);

       unsigned char* p = bin.RawPtr();

       for (int i = 0; i < arraySize; i++)

       {

              p[i] = (unsigned char) i%255;

       }

       bin.SaveFile("binData.bin");

       bin.ReleaseData();

       BinData tbin;

       tbin.LoadFile("binData.bin");

}

3.2.4          Explicitly Use De-Allocator

This sample code shows how to define and use a de-allocator (CppFree) to releae the memory allocated by malloc.

template<class T>

class CppFree

{

public:

       static void Free(T *p)

       {

              LIPING_PTR_DEBUG_TRACE(p);

              if (p) free((void*)p);

       }

};

 

{

       const int arraySize = 1024*10;

       LipingPtr<char, CppFree<char> >

              cp((char*)malloc(sizeof(char)*arraySize));

       strcpy(cp.RawPtr(), "Hello LipingArray");

       PrintCp(cp.RawPtr(), printit);

}

3.2.5          Use LipingPtr with STL Vector

This sample creates LipingPtr object and put it in STL vector. The LipingPtr managed memory will be released when the vector (tvector) go out of the scope.

This sample also shows the base class LipingPtr Vector can contain different pointers in the same descendent class tree.

 

if (printit) printf("Use LipingPtr with STL Vector:\n");

if (printit) printf("The vector contains the base and derived classes pointers.\n");

{

      std::vector< LipingPtr<LipingPtrTest> > tvecotr;

      for(int i=0; i < 6; i++)

      {

            // Directly put the new pointer into vector:

            if (printit) printf("  >> begin add %d\n", i);

            if (i % 3 == 0)

            {

                  tvecotr.push_back( LipingPtr<LipingPtrTest>(new LipingPtrTest()) );

            }

            else if (i % 3 == 1)

            {

                  tvecotr.push_back( LipingPtr<LipingPtrTest>(new LipingPtrTestD()) );

            }

            else

            {

                  tvecotr.push_back( LipingPtr<LipingPtrTest>(new LipingPtrTestDD()) );

            }

 

            // Assign the new pointer to a temp base pointer, and put it in a vector that

            // is defined as the base class LipingPtr.

            LipingPtrTest* tmpPtr;

            if (i % 3 == 0)

            {

                  tmpPtr = new LipingPtrTest();

                  tvecotr.push_back( tmpPtr );

            }

            else if (i % 3 == 1)

            {

                  tmpPtr = new LipingPtrTestD();

                  tvecotr.push_back( tmpPtr );

            }

            else

            {

                  tmpPtr = new LipingPtrTestDD();

                  tvecotr.push_back( tmpPtr );

            }

 

            if (printit) printf("  << end add   %d\n", i);

      }

      for(unsigned int i=0; i < tvecotr.size(); i++)

      {

            tvecotr[i]->Hello(printit);

      }

}

 

3.2.6          Use LipingPtr with STL Map

a.       Add map element by string ID

{

       typedef LipingPtr<LipingPtrTest> TestPtr;

       map< string, TestPtr > smap;

       smap["hello-1"] = TestPtr(new LipingPtrTest());

       smap["hello-2"] = TestPtr(new LipingPtrTest());

       smap["hello-3"] = TestPtr(new LipingPtrTest());

       map< string, TestPtr >::iterator it;

       for(it = smap.begin(); it != smap.end(); it++)

       {

              if (printit) printf("Index string = %s; ",

                     (*it).first.c_str());

              (*it).second->Hello(printit);

       }

}

  

b.      Different Ways to Add Items in Map

if (printit) printf("Different ways for adding map items:\n");

{

       map< int, TestPtr > imap;

      

       if (printit) printf("  << Two step add:\n");

       TestPtr inputPtr = new LipingPtrTest();

       imap[111] = inputPtr;

       if (printit) printf("  >> End two step add\n");

 

       if (printit) printf("One step add:\n");

       imap[121] = TestPtr(new LipingPtrTest());

       if (printit) printf("end - One step add\n");

 

       if (printit) printf("Two step add by pair:\n");

       PtrPair x(131, new LipingPtrTest());

       imap.insert(x);

       if (printit) printf("end - Two step add by pair\n");

 

       if (printit) printf("One step add by pair:\n");

       imap.insert(PtrPair(141, new LipingPtrTest()));

       if (printit) printf("end - One step add by pair\n");

 

}

  

c.       Put LipingPtr Object as First Map Element

The managed object (LipingPtrTest) must supports “<” operator in order to put the LipingPtr instance in STL map.

{

       typedef LipingPtr<LipingPtrTest> TestPtr;

       typedef pair<TestPtr, int> SiPair;

       map< TestPtr, int > imap;

       imap.insert(SiPair(new LipingPtrTest(), 141));

       imap.insert(SiPair(new LipingPtrTest(), 142));

       imap.insert(SiPair(new LipingPtrTest(), 143));

       map< TestPtr, int >::iterator it;

       for(it = imap.begin(); it != imap.end(); it++)

       {

              if (printit) printf("Int value = %d;  ", (*it).second);

              (*it).first->Hello(printit);

       }

}

  

d.      Use LipingPtr with STL Vector and Sort Algorism

This sample code puts LipingPtr objects into STL vector and sorts them by STL sort method.

{

       const int arraySize = 10;

       typedef LipingPtr<LipingPtrTest> LipingTestPtr;

       typedef vector<LipingTestPtr> VTest;

       VTest ta;

       if (printit) printf("\n");

       if (printit) printf("Print random items:\n");

       for (unsigned int i = 0; i < arraySize; i++)

       {

              LipingTestPtr ptr(new LipingPtrTest);

              ptr->index = (int)(rand());

              ptr->Hello(printit);

              ta.push_back(ptr);

       }

       std::sort(ta.begin(), ta.end());

       VTest::iterator it;

       if (printit) printf("\n");

       if (printit) printf("Print sorted items:\n");

       for (it = ta.begin(); it != ta.end(); it++)

       {

              (*it)->Hello(printit);

       }

       if (printit) printf("\n");

}

  

3.3              Attach, Detach, and ReleaseData Functions

LipingPtr and LipingArray provide Attach, Detach, and ReleaseData functions to directly access the hidden raw pointer. These actions will affect all LipingPtr or LipingArray objects that referring to the same raw pointer. It is not recommended to use these functions often if you can use other functions to complete the task.

Here is a sample code that shows the proper usage for Attach and Detach:

{

       int arraySize = 100;

       int *a = new int[arraySize]; // allocate a new array

       LipingArray<int> ia(a, arraySize); // initialize ia with allocated array

       for (unsigned int i = 0; i < ia.Size(); i++) // assign values for each element

       {

              ia[i] = i;

       }

       {

              int *b = ia.Detach(); // detach the array from ia

              LipingArray<int> ib(b, arraySize); // let ib manage the array pointer

              for (int i = 0; i< arraySize; i++) // change the array element values

              {

                     ib[i] = i*3;

              }

 

              ia.Attach(ib.Detach(), arraySize);

              // detach the array from ib and let ia manage the pointer

                                                      

              LipingArray<int> aa(new int[arraySize], arraySize); // create a new array

              for (int i = 0; i< arraySize; i++) // assign value to aa elements

              {

                     aa[i] = i;

              }

 

              LipingArray<int> ic = ia;

              ia.Attach(aa.Detach(), arraySize);

              // let ia manage aa's array pointer.

              // the old array pointer that ia manages will be released

              // before attach aa's pointer.

  

       }

}

This code section shows the complex Attach, Detach, InitData, SaveFile, and LoadFile functions usage:

{

       LipingArray<long> xx;

       {

              unsigned int arraySize = 100;

              // Allocate the memory by arraySize

              LipingArray<long> a(arraySize);

              // Get the array arraySize by Size

              for (unsigned int i = 0; i < a.Size(); i++)

              {

                     // Access the element by [] operator

                     a[i] = 'a' + i%('z'-'a'+1);

              }

              // Direct access the buffer

              memset(a.RawPtr(), 0, a.Size()*sizeof(long));

              long *lx = new long[arraySize];

              // Attach a pre-allocated memory - the old memory is released

              a.Attach(lx, arraySize);

              // Attach a newly allocated array - the old memory is released

              a.Attach(new long[arraySize], arraySize);

 

              LipingArray<long> aa;

              aa = a;

              LipingArray<long> bb(aa);

              // Detach the allocated memory *** Careful to use!!! Advanced usage!!!

              lx = a.Detach();

              // Release the detached memory

              delete [] lx;

 

              LipingArray<long> cc(arraySize);

              // Get the array arraySize by Size

              for (unsigned int i = 0; i < cc.Size(); i++)

              {

                     // Access the element by [] operator

                     cc[i] = 'a' + i%('z'-'a'+1);

              }

              // Add another reference; the memory will be keept even cc is released

              xx = cc; 

       }

 

       // Release the old memory got from cc; and track a new array

       xx = LipingArray<long>(10);

       // Do nothing

       xx = xx;

 

       XPoint point0;

       point0.x = 12;

       point0.y = 88;

       LipingArray<XPoint> xs(10);

       // set all points by point0 value

       xs.InitData(point0);

       // Save the content in a file

       xs.SaveFile("arrayDump.bin");

       xs.InitData(point0);

       // Load a file in buffer

       xs.LoadFile("arrayDump.bin");

       xs.ReleaseData();

       xs = LipingArray<XPoint>(5);

       // Load a file with a new buffer. The Size() is 10 after load

       xs.LoadFile("arrayDump.bin");

}

 

3.4              Multi Dimensional Array Usage

LipingArray supports multi dimensional arrays. The sample code and comments is listed below.

// Two dimensional array:

{

       unsigned int dx = 10, dy = 8;

       LipingArray<Point, 2> xa(dx, dy);

       for (unsigned int x = 0; x < dx; x++)

       {

              for (unsigned int y = 0; y < dy; y++)

              {

                     Point *p = &xa.Element(x, y);

                     p->x = x;

                     p->y = y;

              }

       }

       for (unsigned int x = 0; x < dx; x++)

       {

              if (printit) printf("\n");

              for (unsigned int y = 0; y < dy; y++)

              {

                     Point *p = &xa.Element(x, y);

                     if (printit) printf("%d,%d  ", p->x, p->y);

              }

       }

       if (printit) printf("\n");

       for (unsigned int y = 0; y < dy; y++)

       {

              if (printit) printf("\n");

              for (unsigned int x = 0; x < dx; x++)

              {

                     Point *p = &xa.Element(x, y);

                     if (printit) printf("%d,%d  ", p->x, p->y);

              }

       }

       if (printit) printf("\n");

 

       xa.SaveFile("arrayDump_xa.bin"); // Save the content in a file

       LipingArray<Point, 2> xl(10, 8);

       xl.LoadFile("arrayDump_xa.bin"); // Load the content from file

       if (printit) printf("\n");

       if (printit) printf("Print loaded two dimensional array:");

       for (unsigned int y = 0; y < dy; y++)

       {

              if (printit) printf("\n");

              for (unsigned int x = 0; x < dx; x++)

              {

                     Point *p = &xl.Element(x, y);

                     if (printit) printf("%d,%d  ", p->x, p->y);

              }

       }

       if (printit) printf("\n");

}

// Three dimensional array:

{

       unsigned int dx = 5, dy = 3, dz = 8;

       LipingArray<CpPoint, 3> xa(dx, dy, dz);

 

       if (printit) printf("Dimensions <%d> Size: ", xa.Dimensions());

       for (unsigned int i = 0; i < xa.Dimensions(); i++)

       {

              if (printit) printf("%d, ", xa.DimSize(i));

       }

 

       for (unsigned int x = 0; x < dx; x++)

       {

              for (unsigned int y = 0; y < dy; y++)

              {

                     for (unsigned int z = 0; z < dz; z++)

                     {

                           CpPoint *p = &xa.Element(x, y, z);

                           p->x = x;

                           p->y = y;

                           p->z = z;

                     }

              }

       }

       for (unsigned int x = 0; x < dx; x++)

       {

              if (printit) printf("\n");

              for (unsigned int y = 0; y < dy; y++)

              {

                     if (printit) printf("\n");

                     for (unsigned int z = 0; z < dz; z++)

                     {

                           CpPoint *p = &xa.Element(x, y, z);

                           if (printit) printf("%d,%d,%d  ", p->x, p->y, p->z);

                     }

              }

       }

       for (unsigned int z = 0; z < dz; z++)

       {

              if (printit) printf("\n");

              for (unsigned int y = 0; y < dy; y++)

              {

                     if (printit) printf("\n");

                     for (unsigned int x = 0; x < dx; x++)

                     {

                           CpPoint *p = &xa.Element(x, y, z);

                           if (printit) printf("%d,%d,%d  ", p->x, p->y, p->z);

                     }

              }

       }

       if (printit) printf("\n\n");

       // The array content will be released when leaving the section.

}

 

// Array assignment:

{

       unsigned int dx = 3, dy = 5, dz = 10;

       LipingArray<Point, 2> xa(dx, dy);

       LipingArray<Point, 3> xb(dx, dy, dz);

       LipingArray<Point, 2> xa1(dx, dy+1);

       xa1 = xa;

       //xa1 = xb;   // Compile time error. - it is by design

                     // to avoid confusion at compile time.

  

       if (printit) printf("Dimensions <%d> Size: ", xa.Dimensions());

       for (unsigned int i = 0; i < xa.Dimensions(); i++)

       {

              if (printit) printf("%d, ", xa.DimSize(i));

       }

}

  

3.5              Supported Operators

LipingPtr supports the following operators:

LipingPtr& operator=(const LipingPtr& inputPtr);

LipingPtr& operator=(T* rawPointer);

T* operator->() const;

T& operator*() const;

bool operator!=(const void* p) const;

bool operator!() const;

bool operator==(const void* p) const;

bool operator!=(const LipingPtr &inputPtr) const;

bool operator==(const LipingPtr &inputPtr) const;

bool operator<(const LipingPtr &inputPtr) const;

Here is the sample code which uses the supported operators.

{

       // Different constructors:

       LipingPtr<LipingPtrTest> p1(new LipingPtrTest);

       LipingPtr<LipingPtrTest> p2(p1);

       LipingPtr<LipingPtrTest> p3 = p1;

       LipingPtr<LipingPtrTest> p4(NULL);

       CallHello(p4);

       if (p4 != NULL)

       {

              p4->Hello(printit);

              (*p4).Hello(printit);

       }

       if (p4 == NULL)

       {

              if (printit) printf("   Use == operator to check ===> p4 is NULL\n");

       }

       if (!p4)

       {

              if (printit) printf("   Use ! operator to check ===> p4 is NULL\n");

       }

       p4 = p1;

       CallHello(p4);

       if (p4 != NULL)

       {

              p4->Hello(printit);

              (*p4).Hello(printit);

       }

       if (p4 == NULL)

       {

              if (printit) printf("   ===> p4 is NULL\n");

       }

 

       LipingPtr<LipingPtrTest> p5(new LipingPtrTest);

       LipingPtr<LipingPtrTest> p6(new LipingPtrTest);

 

       if (printit) printf("Call member by -> operator:\n");

       p5->Hello(printit);

       p6->Hello(printit);

 

       if (printit) printf("Call member by * operator:\n");

       (*p5).Hello(printit);

       (*p6).Hello(printit);

 

       p1 = p5;

       LipingPtr<LipingPtrTest> p7(p1);

       LipingPtr<LipingPtrTest> p8 = p1;

       LipingPtr<LipingPtrTest> p9(p1);

       if (p8 == p1)

       {

              if (printit) printf("p8 == p1\n");

       }

       if (p8 != p1)

       {

              if (printit) printf("p8 != p1\n");

       }

       p8 = p2;

       if (p8 == p1)

       {

              if (printit) printf("p8 == p1\n");

       }

       if (p8 != p1)

       {

              if (printit) printf("p8 != p1\n");

       }

}

 

// more about operator “=” :

{

       LipingPtr<ChPoint> xa1 = new ChPoint(1,2);

       ChPoint *p2 = new ChPoint(2,2);

       xa1 = p2;

       LipingPtr<ChPoint> xa2 = new ChPoint(3,1);

       xa1 = xa2;

       LipingPtr<ChPoint> xa3;

       xa3 = xa1 = xa2 = new ChPoint(3,3);

}

4.    Use LipingPtr Manage Other Pointers Sample

Here is a sample that shows how to use LipingPtr to manage Intel OpenCV image pointer.

4.1              Define a De-Allocator for OpenCV IplImage

struct CvReleaseIplImage

{

       static void Free(IplImage *p)

       {

              if (p) cvReleaseImage(&p);

       }

};

 

typedef LipingPtr<IplImage, CvReleaseIplImage> CvImagePtr;

4.2              Use Defined Type to Return CvImagePtr Pointer

The returned image will be released automatically when no one reference to it.

CvImagePtr GetImageEdge(IplImage * sourceImage, float edgeThresh)

{

       IplImage *distImage  = cvCreateImage(

              cvSize(sourceImage->width,sourceImage->height), IPL_DEPTH_8U, 1);

CvImagePtr distPtr(distImage);

cvCanny(sourceImage, distImage, (float)edgeThresh, (float)edgeThresh*3, 3);

       cvNot( distImage, distImage );

return distPtr ;

}

5. Use Base Class LipingPtr Manage Descendent Class Pointers

5.1 Description

If LipingPtr is declared for a base class, it will be able to manage all the descendent class pointers. From which, C++ polymorphism is kept.

5.2 Sample Code

// Use Base Class LipingPtr Manage Descendent Class Pointers

{

      LipingPtr<LipingPtrTest> tmpPtr;

      tmpPtr = new LipingPtrTest();

      tmpPtr->Hello(printit);

      tmpPtr = new LipingPtrTestD();

      tmpPtr->Hello(printit);

      tmpPtr = new LipingPtrTestDD();

      tmpPtr->Hello(printit);

}

The sample code for LipingPtr Vector also shows this usage.

6.    Demo Class Definition

6.1              Data Structures Used in Sample Code

const int MaxNameLen = 50;

struct MyRec

{

       char name[MaxNameLen];

       int age;

};

 

struct Point { int x; int y; };

 

struct XPoint { int x; int y; };

 

struct CpPoint

{

       char x;

       char y;

       char z;

};

 

struct ChPoint

{

       char x;

       char y;

       ChPoint(char ix, char iy):x(ix), y(iy) {};

};

6.2              LipingPtrTest.h

LipingPtrTest.h file content:

#pragma once

 

#include "LipingPtr.h"

 

class LipingPtrTest

{

public:

      bool printit;

      int index;

      static int counter;

 

public:

      LipingPtrTest();

      LipingPtrTest(bool printTrace);

      ~LipingPtrTest();

      virtual void Hello(bool printit);

      bool operator<(const LipingPtrTest &xobj) const;

};

 

class LipingPtrTestD : public LipingPtrTest

{

public:

      void Hello(bool printit);

};

 

class LipingPtrTestDD : public LipingPtrTestD

{

public:

      void Hello(bool printit);

};

  

6.3              LipingPtrTest.cpp

  

#include "LipingPtrTest.h"

#include <string>

#include <vector>

#include <map>

 

int LipingPtrTest::counter = 0;

 

LipingPtrTest::LipingPtrTest() : index(0), printit(true)

{

      LIPING_PTR_DEBUG_TRACE(this);

      index = counter++;

#ifdef LIPING_PTR_OUTPUT_DEBUG_TRACE

      if (printit) printf("Object:%p; index:%d\n", this, index);

#endif

}

 

LipingPtrTest::LipingPtrTest(bool printTrace) : index(0), printit(printTrace)

{

      LIPING_PTR_DEBUG_TRACE(this);

      index = counter++;

#ifdef LIPING_PTR_OUTPUT_DEBUG_TRACE

      if (printit) printf("Object:%p; index:%d\n", this, index);

#endif

}

 

LipingPtrTest::~LipingPtrTest()

{

      LIPING_PTR_DEBUG_TRACE(this);

}

 

void LipingPtrTest::Hello(bool printit)

{

      LIPING_PTR_DEBUG_TRACE(this);

      if (printit) printf("LipingPtrTest [%d] [%p]\n", index, this);

}

 

bool LipingPtrTest::operator<(const LipingPtrTest &xobj) const

{

      bool retval = this->index < xobj.index;

      return retval;

}

 

void LipingPtrTestD::Hello(bool printit)

{

      LIPING_PTR_DEBUG_TRACE(this);

      if (printit) printf("LipingPtrTestD [%d] [%p]\n", index, this);

}

 

void LipingPtrTestDD::Hello(bool printit)

{

      LIPING_PTR_DEBUG_TRACE(this);

      if (printit) printf("LipingPtrTestDD [%d] [%p]\n", index, this);

}

 

 

7.    Copyright and Permission

  

Copyright (c) 2008 Liping Dai. All rights reserved.

Web: www.lipingshare.com

Email: lipingsharemail@gmail.com

  

Copyright and Permission Details:

=================================

Permission is hereby granted, free of charge, to any person

obtaining a copy of this software and associated documentation

files (the "Software"), to deal in the Software without

restriction, including without limitation the rights to use,

copy, modify, merge, publish, distribute, and/or sell copies

of the Software, subject to the following conditions:

  

1. Redistributions of the source code must retain the above

copyright notice, this list of conditions and the following

disclaimer.

  

THE SOFTWARE PRODUCT IS PROVIDED "AS IS" WITHOUT WARRANTY OF

ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED

TO, THE IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT,

MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

 

8. Update History

Update History:

07/22/2008: Initial Post

 

08/21/2008: Added ArraySizeType for LipingArray

      The default ArraySizeType is “unsigned long”.

 

08/29/2008: Changed LipingArray default array size type to size_t.

      size_t uses 4 bytes for 32 bits builds; 8 bytes for 64 bits builds.

 

      The user can expecially redefine the array size type; for example:

      typedef LipingArray<CpPoint, 3, CppDeleteArray<CpPoint>, size_t> TDArray;

      TDArray::ArraySizeType dx = 5, dy = 3, dz = 8;

      TDArray xa(dx, dy, dz);

 

      if (printit) printf("Sizeof(ArraySizeType) = %d;  Dimensions <%d>; Sizes for each dimension: ",

            sizeof(TDArray::ArraySizeType), xa.Dimensions());

      for (unsigned int i = 0; i < xa.Dimensions(); i++)

      {

            if (printit) printf("%d, ", xa.DimSize(i));

      }

 

08/30/2008:

      1. Added “Use Base Class LipingPtr Manage Descendent Class Pointers” description.

2. Modified Sample Code for Using LipingPtr with STL Vector

         The sample shows the base class LipingPtr Vector can contain different pointers

         in the same descendent class tree.

 

 

_ END _