Jo said:
Hey,
Thanks for your opinions.
The reason why i want to differentiate between static and dynamic
objects is because of a standard reference counting system.
Each object in the system has a reference count, initially 0 at
construction time.
A reference counting mechanism should be held by a smart_ptr or the
equivalent thereof. Otherwise you'll end up with 2 distinct
implementations of the CObject class.
When the object is used, the reference count is incremented; when it's
released the ref count is decremented.
When the object's ref count gets 0 again, it's automatically deleted.
Simple code:
class CObject {
int RefCount;
CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0) delete this; }
};
But what if the object is statically allocated?! Then it may not be
deleted via 'delete' of course.
The above can be done with a smart_ptr. The smart_ptr does the
reference counting and deletion of the object it is tracking. It zaps
the Object when appropriate. You would not design a class with a
reference count if you where to allocate the class on the stack and on
the heap.
The goal here is to give another object the duty of tracking a
reference count. The advantage is evident: you could ref_count any
type, not just CObject.
By the way, CObject should be called Object (we know its a class, thats
what C stands for).
Whether some objects are allocated dynamically or statically just
depends on the situation, and on the object itself too. (note that the
above class may be a very base class). I don't think it's a matter of
poor design.
So that's in fact why i've put the question.
If i understand your answers well, i could make the CObject class like this:
class CObject {
int RefCount;
bool IsStatic;
CObject() { RefCount=0; }
void Lock() { RefCount++; }
void Unlock() { RefCount--; if (RefCount<=0 && !IsStatic)
delete this; }
void MarkAsStatic() { IsStatic=true; }
};
And then everywhere in the code where an object is allocated statically,
a line must be added: object.MarkAsStatic();
Is that correct? Aren't there any simpler alternatives?
Consider boost's shared_ptr, its heavily used in modern C++. Very
simple to use and rock solid.
You can always write your own reference counting smart_ptr. It just
doesn't make sense to write a smart_ptr that only deals with Objects.
I'ld strongly recommend boost's shared_ptr for this purpose. Its
copyable and therefore can be used in STL containers (unlike <memory>'s
std::auto_ptr).
http://www.boost.org/libs/smart_ptr/shared_ptr.htm
#include <boost/shared_ptr.hpp>
int main()
{
boost::shared_ptr< CObject > sp_obj( new CObject ); // ref counted
Object
typedef boost::shared_ptr< CObject > SPtr_Obj;
// a container of shared_ptrs to Objects
std::vector< SPtr_Obj > v;
v.push_back( SPtr_Obj(new CObject) );
}
The CObject instance at sp_obj will get automatically zapped at the end
of main(). The instance of CObject in the std::vector will
automatically get zapped when the vector is itself destroyed.
That basicly gives the responsability of allocation/deallocation to the
smart_ptr. And your Object class needs not be modified in any way.
Yes, you can have a Cake and eat it too.
Or is there something wrong with my the design of this ref-counting system?
Cheers,
Jo
--------------020901060602050002080207
Content-Type: text/html
X-Google-AttachSize: 4644
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
<tt>Hey,<br>
<br>
Thanks for your opinions.<br>
<br>
The reason why i want to differentiate between static and dynamic
objects is because of a standard reference counting system.<br>
<br>
Each object in the system has a reference count, initially 0 at
construction time.<br>
When the object is used, the reference count is incremented; when it's
released the ref count is decremented.<br>
When the object's ref count gets 0 again, it's automatically deleted.<br>
<br>
Simple code:<br>
<br>
</tt>
<blockquote><tt>class CObject {</tt><br>
<br>
<tt> int RefCount;</tt><br>
<br>
<tt> </tt><tt>CObject() { </tt><tt>RefCount=0; }</tt><br>
<tt> void Lock() { </tt><tt>RefCount++; }</tt><tt></tt><br>
<tt> void Unlock() { </tt><tt>RefCount--; if (RefCount<=0)
delete this; }</tt><br>
<tt>};</tt><br>
</blockquote>
<tt><br>
But what if the object is statically allocated?! Then it may not be
deleted via 'delete' of course.<br>
<br>
W</tt><tt>hether some objects are allocated dynamically or statically</tt><tt>
just depends on the situation, and on the object itself too. (note that
the above class may be a very base class). </tt><tt>I don't think it's
a matter of poor design.</tt><br>
<tt><br>
So that's in fact why i've put the question.<br>
<br>
If i understand your answers well, i could make the CObject class like
this:<br>
<br>
</tt>
<blockquote><tt>class CObject {</tt><br>
<tt></tt><br>
<tt> int RefCount;</tt><br>
<tt> bool IsStatic;</tt><br>
<tt></tt><br>
<tt> </tt><tt>CObject() { </tt><tt>RefCount=0; }</tt><br>
<tt> void Lock() { </tt><tt>RefCount++; }</tt><br>
<tt> void Unlock() { </tt><tt>RefCount--; if (RefCount<=0
&& !</tt><tt>IsStatic</tt><tt>) delete this; }</tt><br>
<tt> void </tt><tt>MarkAsStatic</tt><tt>() { IsStatic=true; }</tt><br>
<tt>};</tt><br>
</blockquote>
<tt>
</tt><br>
<tt>And then everywhere in the code where an object is allocated
statically, a line must be added: object.MarkAsStatic();<br>
<br>
Is that correct? Aren't there any simpler alternatives?<br>
<br>
Or is there something wrong with my the design of this ref-counting
system?<br>
<br>
Cheers,<br>
<br>
Jo<br>
<br>
<br>
</tt>Salt_Peter wrote:<br>
<blockquote type="cite"
cite="(e-mail address removed)">
<pre wrap="">Jo wrote:
</pre>
<blockquote type="cite">
<pre wrap="">Hi,
How can i differentiate between static and dynamic allocated objects?
For example:
void SomeFunction1() {
CObject *objectp = new CObject;
CObject object;
SomeFunction2(objectp,&object);
}
void SomeFunction2(CObject *op1,CObject *op2) {
// now how do i know whether op1/op2 was statically or dynamically
allocated?
// and thus whether i may call a 'delete' on it?
}
Thanks,
Jo
</pre>
</blockquote>
<pre wrap=""><!---->
Thats your responsability. In the same breath that the CObject labelled
as object is a local variable in SomeFunction1(). Remember: new removes
all responsability the compiler has to destroy / recover that
allocation. You've dissmissed the compiler's duties.
There is a lot you can do to help. One might be to use a smart pointer
instead of new/delete. Another is to not allocate as its not required
in the example given. Properly naming your objects goes a long way too.
And in the case you do choose to new and delete, don't give one
function or class the responsability to new and another function or
class the responsabilty to delete (distribute allocations as a
responsability to one entity only - that is a sacred law, it can't be
over-emphasized).
void SomeFunction1() {
CObject *p_object = new CObject;
CObject object;
SomeFunction2( *p_object, object );
delete p_object;
}
void SomeFunction2( CObject& op1, CObject& op2 ) {
// now how do i know whether...
// answer: its not my responsability
}
pass arguements by reference, not pointers
and pass by const reference if you aren't modifying the args
Theres more, you can load CObjects in a std::vector. Assuming that
CObject is copyable and assignable.
#include <vector>
std::vector< CObject > vobj(1000000); // one million default CObjects
</pre>
</blockquote>
</body>
</html>
--------------020901060602050002080207--
Please...
don't top post. Your responses should go inline so that the discussion
can be followed by others.
Also, post in plain text, not html.