472,780 Members | 2,132 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,780 software developers and data experts.

Two smartpointer designs

I've made two smartpointers that I'd like to share. Improvements and
comments are welcome.

The key to both is that there should be no access to the managed
object, and all operations should be done on the smartpointers. Both
are designed in a similar way, where a userclass inherits from a
template and the smartpointer is defined as an internal class of the
template;

The first one is an automatic refcount smartpointer where the object
pointed to keeps track of the current refcount, and the object gets
destroyed if the refcount goes to 0. All refcount management is
automatic.

The second is called a safepointer, and the managed object will
automatically clear all safepointers which references it when
destroyed. Destruction is done through a smartpointer's destroy
function.

I'm including a testfile which shows how they are used, followed by
the 2 template files:
// ConsoleTests.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"
#include "../../common/autorefcount.h"
#include "../../common/safepointer.h"

class A;
class A : public TAutoRefable<A*>
{
public:
static ARPtr Create(int x){return ARPtr(new A(x));} // create an
instance of A

int GetX(){return mX;}
private:
A(int x) : mX(x){} // keep constructors private in inherited classes,
and use Create to instanciate

int mX;
};

void TestAutoRefPointer(){
A::ARPtr c;
bool valid = c.IsValid(); // false

c = A::Create(1);
if (c.IsValid()) { // true
int x = c->GetX();
}

DWORD refcount = c.GetRefCount();// refcount = 1

{
A::ARPtr d(c);
refcount = c.GetRefCount();// refcount = 2
{
A::ARPtr e;
e = c;
refcount = c.GetRefCount();// refcount = 3
}
refcount = c.GetRefCount();// refcount = 2
}
refcount = c.GetRefCount();// refcount = 1

valid = c.IsValid(); // true
c.Clear(); // refcount = 0, object gets destroyed
refcount = c.GetRefCount();// refcount = 0
valid = c.IsValid(); // false

}
class S;
class S : public TSafeObj<S*>
{
public:
static SPtr Create(int x){return SPtr(new S(x));} // create an
instance of S
int GetX(){return mX;}

private:
S(int x) : TSafeObj<S*>(5), mX(x){}// keep constructors private in
inherited classes, and use Create to instanciate
int mX;
};
void TestSafePointer(){
S::SPtr c;

bool valid = c.IsValid(); // false

c = S::Create(1);
if (c.IsValid()){ // true
int x = c->GetX();
}

S::SPtr d(c);
S::SPtr e;
e = c;

d.Destroy(); // destroys object, and clears all SafePointers to it
if (c.IsValid() || d.IsValid() || e.IsValid()) {// false
int x = c->GetX();
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TestAutoRefPointer();
TestSafePointer();
return 0;
}
// autorefcount - ptr with auto refcount

#pragma once
#include "comdef.h"
template <class Tclass TAutoRefable
{
public:
class ARPtr
{
public:
ARPtr() : mPtr(NULL){}
ARPtr(T p) : mPtr(p) {
if (p) {
p->AddRef();
}
}
ARPtr(const ARPtr& s) : mPtr(s.mPtr){
if (mPtr) {
mPtr->AddRef();
}
}
~ARPtr()
{
if (mPtr){
mPtr->SubRef();
}
}
DWORD GetRefCount(){return (mPtr) ? mPtr->mRefCount : 0;}

T operator -(){return mPtr;}
ARPtr& operator =(const ARPtr& that){
if (this != &that) {
if (mPtr){
mPtr->SubRef(); // deletes object if refcount goes to 0, so mPtr
can point to freed mem after this.
}
if (that.mPtr) {
that.mPtr->AddRef();
}
mPtr = that.mPtr;
}
return *this;
}

void Clear(){
if (mPtr){
mPtr->SubRef();
}
mPtr = NULL;
}

bool IsValid(){return mPtr != NULL;}

private:
T mPtr;
};

// initial values for event and subsciber dynamic arrays
static ARPtr Create(){return ARPtr(NULL);} // override this with more
interesting actions
protected: // keep constructors and destructors protected/private in
inherited classes
TAutoRefable() : mRefCount(0){}
virtual ~TAutoRefable(){}

private:
friend ARPtr;
void AddRef(){mRefCount++;}
void SubRef(){--mRefCount; if (mRefCount == 0) delete this;}

DWORD mRefCount;
};
// SafePtr - clears all safeptrs when object is destroyed

#pragma once
#include "comdef.h"
#include "objectarray.h"

template <class Tclass TSafeObj
{
public:
class SPtr
{
public:

SPtr() : mPtr(NULL){}
SPtr(T p) : mPtr(p) {if (mPtr) mPtr->AddSPtr(this);}
SPtr(const SPtr& s) : mPtr(s.mPtr){
if (mPtr) mPtr->AddSPtr(this);
}
~SPtr(){if (mPtr) mPtr->RemoveSPtr(this);}

void Destroy(){
if (mPtr){
mPtr->RemoveSPtr(this);
delete mPtr; // mPtr clears out other sptrs
mPtr = NULL;
}
}
T operator -(){return mPtr;}
SPtr& operator =(const SPtr& that){
if (this != &that) {
if (mPtr) mPtr->RemoveSPtr(this);
if (that.mPtr) that.mPtr->AddSPtr(this);
mPtr = that.mPtr;
}
return *this;
}

void Clear(){
if (mPtr) mPtr->RemoveSPtr(this);
mPtr = NULL;
}

bool IsValid(){return mPtr != NULL;}

private:
friend TSafeObj;
T mPtr;

};

static SPtr Create(){return SPtr(NULL);} // override with more useful
actions

protected: // keep destructor and constructor protected/private in
inherited classes
friend SPtr;

TSafeObj(DWORD ptrCount) : mSafePtrs(ptrCount){} // set up initial
pointercount

virtual ~TSafeObj(){
for (DWORD i = 0; i < mSafePtrs.Size(); ++i) mSafePtrs[i]->mPtr =
NULL;
}
private:
typedef TObjectArray<SPtr*SafePtrArray;

void AddSPtr(SPtr* sptr){mSafePtrs.Add(sptr);}
void RemoveSPtr(SPtr* sptr){mSafePtrs.RemoveObj(sptr);}

SafePtrArray mSafePtrs; // Sptrs to this object
};

Dec 1 '07 #1
0 1132

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: Scotter | last post by:
Okay I think my title line was worded misleadingly. So here goes again. I've got quite 20 identical MDB files running on an IIS5 server. From time to time I need to go into various tables and add...
145
by: Mark Johnson | last post by:
Oddly enough, I found it difficult, using Google, to find a list of best-of sites based on the quality of their css packages. So I'd ask. Does anyone know of particularly good sites which are in...
2
by: Tobias Kilian | last post by:
Hi Ng ! I wrote a SmartPointer class which holds a doubled linked list to all its copies to ensure that all copies are holding the same pointer, even if one copy changes later. If the last...
15
by: mathieu | last post by:
Hi, I have implemented a SmartPointer class following the implementation proposed by Bill Hubauer(*). But I also override the operator * () template<class ObjectType> class SmartPointer {...
2
by: coder_lol | last post by:
MS VS 7.0 happily resolves by SmartPointer and Inheritance, but I got to use another target compiler and it does not accept user conversion for templates. Can I forced a recast somehow? I have...
0
by: service0073 | last post by:
Designs For Fine Jewelry Pieces Fine jewelry is created from the finest precious metals and the gems that are set in these metals could be what makes the jewelry so fine. Jewelry lovers can wear...
8
by: Prisoner at War | last post by:
As 16:9 widescreens become more common, are there any designs which are specifically created to somehow exploit any advantages offered by letterbox dimensions? How to remain backwards-compatible...
0
by: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.