By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,617 Members | 1,600 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,617 IT Pros & Developers. It's quick & easy.

Yet Another Question About Smart Pointers (YAQAS)

P: n/a
Hello,

I've been trying to implement smart pointers in C++ (combined with a
reference counter) because I want to do some memory management. My code
is based on the gamedev enginuity articles, various books and ...
whatever I could find on the subject :-)

I'll leave out the reference counter part because its pretty basic, but
my reference counter class is called xObject. My smart pointer class is
called xPointer.

My problem is that I can't figure out how to make my smart pointer
object a pointer. Look at the following code:

--------------- CUT
void test()
{
//xShaderResource is derived from xObject
class xPointer<xShaderResource> myShader2 = new xShaderResource();
myShader2->loadResource(NULL); //testing
}
--------------- CUT

This works like a charm. The xShaderResource object will be destroyed in
my garbage collector because myShader2 is beeing destructed after it
goes out of scope when test() returns.

So far so good, but what if let's say I have a vector/list with 1000+
xPointer objects (imagine a resource manager)? They will never go out of
scope, right?

What I need is to do something like this:

--------------- CUT
class xPointer<xShaderResource> *myShader2 = new
xPointer<xShaderResource>(new xShaderResource());
myShader2->loadResource(NULL);
--------------- CUT

This should enable me to run through the list and do something like this:

delete (*iterator);

on relevant objects thus forcing them to go away and get collcected. Can
this be done? I kinda figure I need to change/add my operators
somewhere, but I can't figure out how :-(

Can anyone help?

-------------------------------- Relevant code
template<class X>
class xPointer
{
protected:
X* obj;
public:

xPointer()
{
obj = 0;
}

xPointer(X *oP)
{
obj = 0;
*this = oP;
}

~xPointer()
{
if( obj )
obj->Release();
}

X& operator*(void) { return *obj; }

void operator =(X *oP)
{
if( obj )
obj->Release();
obj = oP;
if( obj )
obj->Alloc();
}

void operator =(const xPointer<X> &oP)
{
if( obj )
obj->Release();
obj = oP.obj;
if( obj )
obj->Alloc();
}

X* operator ->(void)
{
return obj;
}
};
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
"Johnny Hansen" <we*******@suxx.dk> wrote in message
news:cj**********@news.cybercity.dk...
Hello,

I've been trying to implement smart pointers in C++ (combined with a
reference counter) because I want to do some memory management. My code
is based on the gamedev enginuity articles, various books and ...
whatever I could find on the subject :-)

I'll leave out the reference counter part because its pretty basic, but
my reference counter class is called xObject. My smart pointer class is
called xPointer.

My problem is that I can't figure out how to make my smart pointer
object a pointer. Look at the following code:

--------------- CUT
void test()
{
//xShaderResource is derived from xObject
class xPointer<xShaderResource> myShader2 = new xShaderResource();
myShader2->loadResource(NULL); //testing
}
--------------- CUT

This works like a charm. The xShaderResource object will be destroyed in
my garbage collector because myShader2 is beeing destructed after it
goes out of scope when test() returns.

So far so good, but what if let's say I have a vector/list with 1000+
xPointer objects (imagine a resource manager)? They will never go out of
scope, right?

What I need is to do something like this:

--------------- CUT
class xPointer<xShaderResource> *myShader2 = new
xPointer<xShaderResource>(new xShaderResource());
myShader2->loadResource(NULL);
--------------- CUT

This should enable me to run through the list and do something like this:

delete (*iterator);

on relevant objects thus forcing them to go away and get collcected. Can
this be done? I kinda figure I need to change/add my operators
somewhere, but I can't figure out how :-(

Can anyone help?
[...]


Well, first consider using a reference-counted pointer library. If you want
to write your own, then take a look at the FAQ's answers about reference
counting (http://www.parashift.com/c++-faq-lite/ Section 16 items 21 "How do
I do simple reference counting" on), because they contain useful snippets of
code for implementing reference counting.

Now, once you have a working reference-counted smart pointer stored in a
std::list or std::vector, removing elements so that the managed
reference-counted object may be deallocated is about as simple as removing
any other element from the container. A simple example (using std::list)

std::list<smartpointertype>::iterator it = /* something to remove */;
myList.erase( it );

will remove the smart pointer from the std::list, causing the smart
pointer's destructor to be invoked, which will cause the managed object's
reference count to be decreased by one (and deallocated, etc if
appropriate).

--
David Hilsee
Jul 22 '05 #2

P: n/a

"Johnny Hansen" <we*******@suxx.dk> wrote in message
news:cj**********@news.cybercity.dk...
Hello,

I've been trying to implement smart pointers in C++ (combined with a
reference counter) because I want to do some memory management. My code is
based on the gamedev enginuity articles, various books and ... whatever I
could find on the subject :-)

I'll leave out the reference counter part because its pretty basic, but my
reference counter class is called xObject. My smart pointer class is
called xPointer.

My problem is that I can't figure out how to make my smart pointer object
a pointer. Look at the following code:

--------------- CUT
void test()
{
//xShaderResource is derived from xObject
class xPointer<xShaderResource> myShader2 = new xShaderResource();
myShader2->loadResource(NULL); //testing
}
--------------- CUT

This works like a charm. The xShaderResource object will be destroyed in
my garbage collector because myShader2 is beeing destructed after it goes
out of scope when test() returns.

So far so good, but what if let's say I have a vector/list with 1000+
xPointer objects (imagine a resource manager)? They will never go out of
scope, right?
Wrong. They will go out of scope when they are removed from the vector or
list, or when the vector or list itself is destroyed.

What I need is to do something like this:

--------------- CUT
class xPointer<xShaderResource> *myShader2 = new
xPointer<xShaderResource>(new xShaderResource());
myShader2->loadResource(NULL);
--------------- CUT

This should enable me to run through the list and do something like this:

delete (*iterator);


You are undoing the good work that smart pointers do. You are making life
difficult for yourself by going back to raw pointers. Smart pointers are
more powerful than you realise. You don't need to do any more work. You're
done.

john
Jul 22 '05 #3

P: n/a
John Harrison wrote:
You are undoing the good work that smart pointers do. You are making life
difficult for yourself by going back to raw pointers. Smart pointers are
more powerful than you realise. You don't need to do any more work. You're
done.


I must be missing something, because I can't get it to work. Look at this:

std::vector<xPointer<xShaderResource>*> myList;
//defined in global scope for testing purposes
//should be stored in my resource-manager object

------------------ CUT
void test()
{
class xPointer<xShaderResource> myResource = new xShaderResource();

myList.push_back(&myResource);
(*myList[0])->loadResource(NULL);
}
------------------ CUT

When test() returns my "myResource" still gets destructed. I assume its
because the myList only contains a pointer to the local global scope
object, thus will contain a invalid pointer when test() returns. Not good.

However trying to do:
std::vector<xPointer<xShaderResource>> myList;

fails miserably. How can I store the actual object in the list, not only
the pointer? This is what I want (i think) :-)


Jul 22 '05 #4

P: n/a

"Johnny Hansen" <we*******@suxx.dk> wrote in message
news:ck***********@news.cybercity.dk...
John Harrison wrote:
You are undoing the good work that smart pointers do. You are making life difficult for yourself by going back to raw pointers. Smart pointers are
more powerful than you realise. You don't need to do any more work. You're done.
I must be missing something, because I can't get it to work. Look at this:

std::vector<xPointer<xShaderResource>*> myList;


Why use smart pointers if you then just go and use ordinary pointers on top?

std::vector<xPointer<xShaderResource> > myList;

Now all your problems go away.
//defined in global scope for testing purposes
//should be stored in my resource-manager object

------------------ CUT
void test()
{
class xPointer<xShaderResource> myResource = new xShaderResource();

myList.push_back(&myResource);
myList.push_back(myResource);
(*myList[0])->loadResource(NULL);
myList[0]->loadResource(NULL);
}
------------------ CUT

When test() returns my "myResource" still gets destructed. I assume its
because the myList only contains a pointer to the local global scope
object, thus will contain a invalid pointer when test() returns. Not good.

However trying to do:
std::vector<xPointer<xShaderResource>> myList;

fails miserably. How can I store the actual object in the list, not only
the pointer? This is what I want (i think) :-)


If this fails miserably, it must be because your smart pointer is not coded
correctly. How does it fail? Could you post the code.

john
Jul 22 '05 #5

P: n/a
>
If this fails miserably, it must be because your smart pointer is not coded correctly. How does it fail? Could you post the code.


OK, looking at the code you posted earlier, the problem is that you have not
defined a copy constructor for your smart pointer.

Something like this is needed

xPointer(const xPointer<X> &oP)
{
obj = oP.obj;
if( obj )
obj->Alloc();
}

john
Jul 22 '05 #6

P: n/a
John Harrison wrote:
If this fails miserably, it must be because your smart pointer is not

coded
correctly. How does it fail? Could you post the code.

OK, looking at the code you posted earlier, the problem is that you have not
defined a copy constructor for your smart pointer.
Something like this is needed
xPointer(const xPointer<X> &oP)
{
obj = oP.obj;
if( obj )
obj->Alloc();
}


Ahh, I've only done the =copy constructor. It works now! I owe you one,
thanks alot :-)
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.