Online Book Reader

Home Category

Professional C__ - Marc Gregoire [379]

By Root 1507 0

class SuperSmartPointer

{

public:

explicit SuperSmartPointer(T* inPtr);

virtual ~SuperSmartPointer();

SuperSmartPointer(const SuperSmartPointer& src);

SuperSmartPointer& operator=(const SuperSmartPointer& rhs);

const T& operator*() const;

const T* operator->() const;

T& operator*();

T* operator->();

operator void*() const { return mPtr; }

protected:

T* mPtr;

static std::map sRefCountMap;

void finalizePointer();

void initPointer(T* inPtr);

};

template

std::map SuperSmartPointer::sRefCountMap;

template

SuperSmartPointer::SuperSmartPointer(T* inPtr)

{

initPointer(inPtr);

}

template

SuperSmartPointer::SuperSmartPointer(const SuperSmartPointer& src)

{

initPointer(src.mPtr);

}

template

SuperSmartPointer&

SuperSmartPointer::operator=(const SuperSmartPointer& rhs)

{

if (this == &rhs) {

return *this;

}

finalizePointer();

initPointer(rhs.mPtr);

return *this;

}

template

SuperSmartPointer::~SuperSmartPointer()

{

finalizePointer();

}

template

void SuperSmartPointer::initPointer(T* inPtr)

{

mPtr = inPtr;

if (sRefCountMap.find(mPtr) == sRefCountMap.end()) {

sRefCountMap[mPtr] = 1;

} else {

sRefCountMap[mPtr]++;

}

}

template

void SuperSmartPointer::finalizePointer()

{

if (sRefCountMap.find(mPtr) == sRefCountMap.end()) {

throw std::runtime_error("ERROR: Missing entry in map!");

}

sRefCountMap[mPtr]--;

if (sRefCountMap[mPtr] == 0) {

// No more references to this object--delete it and remove from map

sRefCountMap.erase(mPtr);

delete mPtr;

mPtr = nullptr;

}

}

template

const T* SuperSmartPointer::operator->() const

{

return mPtr;

}

template

const T& SuperSmartPointer::operator*() const

{

return *mPtr;

}

template

T* SuperSmartPointer::operator->()

{

return mPtr;

}

template

T& SuperSmartPointer::operator*()

{

return *mPtr;

}

Code snippet from SuperSmartPointer\SuperSmartPointer.cpp

Unit Testing the SuperSmartPointer

The Nothing class defined earlier can be employed for a simple unit test for SuperSmartPointer. One modification is needed to determine if the test passed or failed. Two static members are added to the Nothing class, which track the number of allocations and the number of deletions. The constructor and destructor modify these values instead of printing a message. If the SuperSmartPointer works, the numbers should always be equivalent when the program terminates. Here is the adapted Nothing class:

class Nothing

{

public:

Nothing() { sNumAllocations++; }

virtual ~Nothing() { sNumDeletions++; }

static int sNumAllocations;

static int sNumDeletions;

};

int Nothing::sNumAllocations = 0;

int Nothing::sNumDeletions = 0;

Code snippet from SuperSmartPointer\SuperSmartPointer.cpp

Following is the actual test. Note that an extra set of curly braces is used to keep the SuperSmartPointers in a smaller scope, so the example can show automatic allocation and deallocation self-contained within one block:

Nothing* myNothing = new Nothing();

{

SuperSmartPointer ptr1(myNothing);

SuperSmartPointer ptr2(myNothing);

}

if (Nothing::sNumAllocations != Nothing::sNumDeletions) {

std::cout << "TEST FAILED: " << Nothing::sNumAllocations <<

" allocations and " << Nothing::sNumDeletions <<

" deletions" << std::endl;

} else {

std::cout << "TEST PASSED" << std::endl;

}

Code snippet from SuperSmartPointer\SuperSmartPointer.cpp

A successful execution of this test program will result in the following output:

TEST PASSED

You should also write additional tests for the SuperSmartPointer class. For example, you should test the copy construction and operator= functionality. This is left as an exercise for the reader.

Enhancing This Implementation

The previous SuperSmartPointer implementation is not completely free of problems. Templates exist on a per-type basis. In other words, if you have some SuperSmartPointers that store

Return Main Page Previous Page Next Page

®Online Book Reader