📄 smartptr.html
字号:
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<meta NAME="Author" CONTENT="Stefan Tchekanov">
<meta Name="description" Content="Source codes with MFC">
<meta Name="keywords" Content="SOURCE CODE MFC">
<title>A Smart Pointer Capable of Object Level Thread Synchronization and Reference
Counting Garbage Collection</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<h3 align="center"><font COLOR="#000000">A Smart Pointer Capable of Object Level Thread
Synchronization and Reference Counting Garbage Collection</font></h3>
<hr>
<!-- Author and contact details -->
<p>This article was contributed by <a href="mailto:stefant@iname.com">Stefan Tchekanov</a>.
<ul>
<li><a href="##whats_new">What is new </li>
<li></a><a href="##intro">Introduction</a> </li>
<li><a href="##examples">Examples of how to use SmartPtr</a> </li>
<li><a href="##how_works">How does SmartPtr work?</a> </li>
</ul>
<p> </p>
<p><a name="#whats_new"></a><big><strong>What is new</strong></big>
<ul>
<li>SmartPtr objects can accept different pointer types - <a href="##dif_ptr_types">details</a>
</li>
<li>Passing a SmartPtr object as function parameter or function result is as efficient as
passing an integer value or regular pointer - <a href="##efficency">details</a>.</li>
</ul>
<p> </p>
<p><a name="#intro"></a><big><strong>Introduction</strong></big></p>
<p>The SmartPtr class is a generic wrapper that encapsulates pointers. It keeps track of
the total number of reference counts and performs garbage collection when the pointed
object is no more referenced by any "pointer". In addition SmartPtr can do
Object Level Thread Synchronization for pointed objects. This means that calling the
members of the pointed object is enclosed in Windows critical section and only one thread
at a time can use the object. </p>
<p>SmartPtr stores reference counter and critical section in separate memory block - not
in the pointed object. This causes that you don't have to inherit your classes from
special base one to be able to use SmartPtr as a pointer. And one other think is that you
could use SmartPtr to point objects of scalar types - int, short, long, double .... </p>
<p>SmartPtr is implemented as a template class. Because it has three template parameters
it is annoying to specify all of them each time. This is the reason I have defined three
additional template classes inherited from SmartPtr with appropriate default template
parameters to get three diferent behaviours:
<ul>
<li><strong>Reference Counting Garbage Collection</strong> - SmartPtr will free dynamically
allocated memory automatically. </li>
<li><strong>Synchronized Access without Reference Counting Garbage Collection</strong> -
SmartPtr will perform only Thread synchronization. You should free dynamically allocated
memory in your own. </li>
<li><strong>Synchronized Access with Reference Counting Garbage Collection</strong> -
SmartPtr will perform thread synchronization and will free dynamically allocated memory
for you.</li>
</ul>
<p>These are the classes: </p>
<table border="1" width="100%">
<tr>
<th width="23%" bgcolor="#800080"><font color="#ffffff">Class Name</font></th>
<th width="77%" bgcolor="#800080"><font color="#ffffff">Description</font></th>
</tr>
<tr>
<td width="23%" bgcolor="#e0e0e0"><strong>SmartPtrBase</strong></td>
<td width="77%" bgcolor="#e0e0e0">The SmartPtrBase class is a non template base class for
the SmartPtr class. It should never be used directly. SmartPtr uses it to perform
appropriate type casting</td>
</tr>
<tr>
<td width="23%" bgcolor="#e0e0e0"><strong>SmartPtr</strong></td>
<td width="77%" bgcolor="#e0e0e0">The SmartPtr class is a template base class for the next
classes</td>
</tr>
<tr>
<td width="23%" bgcolor="#e0e0e0"><strong>RefCountPtr</strong></td>
<td width="77%" bgcolor="#e0e0e0">Smart pointers that perform only Reference Counting
Garbage Collection</td>
</tr>
<tr>
<td width="23%" bgcolor="#e0e0e0"><strong>SyncPtr</strong></td>
<td width="77%" bgcolor="#e0e0e0">Smart pointers that perform only Synchronized Access
without Reference Counting Garbage Collection</td>
</tr>
<tr>
<td width="23%" bgcolor="#e0e0e0"><strong>SyncRefCountPtr</strong></td>
<td width="77%" bgcolor="#e0e0e0">Smart pointers that perform both Synchronized Access and
Reference Counting Garbage Collection</td>
</tr>
</table>
<p>All of these classes are equal in their implementation. The different behaviour is
achieved via different default template parameters.You could use any of these four classes
to get any of the three behaviours but then you should specify all parameters.<br>
<br>
The following classes are used inside the SmartPtr implementation and SHOULD NEVER be used
directly.
<ul>
<li>CRefCountRep </li>
<li>CSyncAccessRep </li>
<li>CSyncRefCountRep </li>
<li>CSyncAccess </li>
</ul>
<p><a name="#examples"></a><big><strong>Examples of how to use SmartPtr</strong></big></p>
<p>You should include the file <font color="#800000">SmartPtr.h</font> in your project.</p>
<p>I usually include this line in my <font color="#800000">StdAfx.h</font> file.</p>
<pre><tt><font color="#990000">#include "SmartPtr.h"</font></tt></pre>
<p> </p>
<p>Let's have a class CSomething</p>
<strong>
<p>1. Reference Counting Garbage Collection on CSomething class</strong></p>
<pre><tt><font color="#990000">class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef RefCountPtr<CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1 == NULL ) {
....
}
p2->do();
p1 = NULL;
}// Here the object pointed by p2 WILL BE destroyed automatically
/////////////////////////////////////////////////////////////////////////////</font></tt></pre>
<p> </p>
<p><strong>2. Object Level Thread Synchronization for objects of CSomething</strong></p>
<pre><tt><font color="#990000">class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef SyncPtr<CSOMETHING><CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1.IsNull() ) {
....
}
StartThread( p1 );
p2->do(); // Synchronized with the other thread
p1 = NULL;
} // Here the object pointed by p2 will NOT be destroyed automatically
void ThreadFunc( LPSOMETHING p ) {
p->do(); // Synchronized with the other thread
}// Here the object pointed by p will NOT be destroyed automatically
/////////////////////////////////////////////////////////////////////////////</font></tt></pre>
<p>In this example you will get memory leaks, but the two threads will be synchronized
when trying to call object's members. It is your care to free dynamically allocated
memory.</p>
<p> </p>
<p><strong>3. Object Level Thread Synchronization and Reference Counting Garbage
Collection for objects of CSomething</strong></p>
<pre><tt><font color="#990000">class CSomething {
CSomething();
~CSomething();
.....
void do();
};
typedef SyncRefCountPtr<CSOMETHING><CSomething> LPSOMETHING;
void TestFunct() {
LPSOMETHING p1 = new CSomething;
LPSOMETHING p2 = p1;
if( p1.IsNull() ) {
....
}
StartThread( p1 );
p2->do(); // Synchronized with the other thread
p1 = NULL;
}// Here the object pointed by p2 WILL BE destroyed automatically
// if p in ThreadFunc has already released the object
void ThreadFunc( LPSOMETHING p ) {
p->do(); // Synchronized with the other thread
}// Here the object pointed by p WILL BE destroyed automatically
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -