473,625 Members | 3,318 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Reference Counting

OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:

#pragma once

class SmrtPtrDB
{
public:
SmrtPtrDB():num (0){}
~SmrtPtrDB(){}
void add(){num++;}
void sub(){num--;}
int status(){return num;}
private:
int num;
};

#pragma once
#include "SmrtPtrDB. hpp"

template<class T>
class SmrtPtr
{
public:
SmrtPtr<T>(T* obj=0):ptr(obj) {DataBase.add() ;)
SmrtPtr<T>(cons t SmrtPtr<T>& rhs):ptr(new
T(*(rhs.ptr))){ DataBase.add(); }
~SmrtPtr<T>(){d elete ptr; ptr=0; DataBase.sub(); }
void operator=(T val){*ptr=val;}
SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
delete ptr;
ptr(rhs.ptr);
}
else return this;
}
int status(){DataBa se.status();}
T& operator*()cons t{return *ptr;}
T* operator->()const{retu rn ptr;}
private:
SmrtPtrDB DataBase;
T* ptr;
};

I'm very confused. Am I implementing this right? Thanks!!!!

Jul 10 '06 #1
20 1661
Protoman wrote:
OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:

#pragma once

class SmrtPtrDB
{
public:
SmrtPtrDB():num (0){}
~SmrtPtrDB(){}
void add(){num++;}
void sub(){num--;}
int status(){return num;}
private:
int num;
};

#pragma once
#include "SmrtPtrDB. hpp"

template<class T>
class SmrtPtr
{
public:
SmrtPtr<T>(T* obj=0):ptr(obj) {DataBase.add() ;)
SmrtPtr<T>(cons t SmrtPtr<T>& rhs):ptr(new
T(*(rhs.ptr))){ DataBase.add(); }
~SmrtPtr<T>(){d elete ptr; ptr=0; DataBase.sub(); }
void operator=(T val){*ptr=val;}
SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
delete ptr;
ptr(rhs.ptr);
}
else return this;
}
int status(){DataBa se.status();}
T& operator*()cons t{return *ptr;}
T* operator->()const{retu rn ptr;}
private:
SmrtPtrDB DataBase;
T* ptr;
};

I'm very confused. Am I implementing this right? Thanks!!!!
This is our current counted pointer code:

//
//counted_ptr - simple reference counted pointer.
//
//The is a non-intrusive implementation that allocates an additional
//int and pointer for every counted object.

#ifndef __COUNTED_PTR_H
#define __COUNTED_PTR_H

template <class Xclass counted_ptr
{
public:
typedef X element_type;

explicit counted_ptr(X* p = 0) // allocate a new counter
: itsCounter(0) {if (p) itsCounter = new counter(p);}
~counted_ptr()
{release();}
counted_ptr(con st counted_ptr& r) throw()
{acquire(r.itsC ounter);}
counted_ptr& operator=(const counted_ptr& r)
{
if (this != &r) {
release();
acquire(r.itsCo unter);
}
return *this;
}

template <class Y>
counted_ptr(con st counted_ptr<Y>& r) throw()
{acquire(r.itsC ounter);}
template <class Y>
counted_ptr& operator=(const counted_ptr<Y>& r)
{
if (this != &r) {
release();
acquire(r.itsCo unter);
}
return *this;
}

X& operator*() const throw() {return *itsCounter->ptr;}
X* operator->() const throw() {return itsCounter->ptr;}
X* get() const throw() {return itsCounter ?
itsCounter->ptr : 0;}
bool unique() const throw()
{return (itsCounter ? itsCounter->count == 1 : true);}

private:

struct counter {
counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
X* ptr;
unsigned count;
}* itsCounter;

void acquire(counter * c) throw()
{ // increment the count
itsCounter = c;
if (c) ++c->count;
}

void release()
{ // decrement the count, delete if it is 0
if (itsCounter) {
if (--itsCounter->count == 0) {
delete itsCounter->ptr;
delete itsCounter;
}
itsCounter = 0;
}
}
};

#endif
Jul 10 '06 #2
Jon Rea wrote:
Protoman wrote:
>OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:
It's very hard to understand what it is you're trying to do.

Could you write a snippet of code that describes more about what you're
trying to achieve ? More like a test case for your smart pointer ...
Jul 10 '06 #3

Gianni Mariani wrote:
Jon Rea wrote:
Protoman wrote:
OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:

It's very hard to understand what it is you're trying to do.

Could you write a snippet of code that describes more about what you're
trying to achieve ? More like a test case for your smart pointer ...
Actually here's the code; it achieves reference counting (I hope!!!)

SmrtPtrDB.hpp

#pragma once

class SmrtPtrDB
{
public:
SmrtPtrDB():num (1){}
SmrtPtrDB(const SmrtPtrDB& rhs):num(rhs.nu m){}
~SmrtPtrDB(){}
void add(){num++;}
void sub(){num--;}
int status(){return num;}
private:
int num;
};

SmrtPtr.hpp

template<class T>
class SmrtPtr
{
public:
SmrtPtr<T>(T* obj=0):ptr(obj) {}
SmrtPtr<T>(cons t SmrtPtr<T>& rhs):ptr(rhs.pt r){DataBase.add ();}
~SmrtPtr<T>()
{
DataBase.sub();
if(DataBase.sta tus()==0)
{delete ptr;cout << "Deleted."; }
else cout << "Out of scope. " << endl;
}
void operator=(T val){*ptr=val;}
void operator=(T* val){ptr=val;}
SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
delete ptr;
ptr(rhs.ptr);
}
else return this;
}
int status(){return DataBase.status ();}
T& operator*()cons t{return *ptr;}
T* operator->()const{retu rn ptr;}
operator T*()const{retur n ptr;}
private:
SmrtPtrDB DataBase;
T* ptr;
};

main.cpp

#include <iostream>
#include <cstdlib>
#include "SmrtPtr.hp p"
using namespace std;

int main()
{
{
SmrtPtr<intptr( new int);
ptr=5;
cout << *ptr << endl;
{
SmrtPtr<intptr2 (ptr);
ptr2=6;
cout << *ptr << endl;
cout << *ptr2 << endl;
}
cout << *ptr << endl;
}
system("PAUSE") ;
return EXIT_SUCCESS;
}
It works apparently. Could you help me improve? Thanks!!!!

Jul 10 '06 #4
Protoman schrieb:
Gianni Mariani wrote:
>Jon Rea wrote:
>>Protoman wrote:

OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:
It's very hard to understand what it is you're trying to do.

Could you write a snippet of code that describes more about what you're
trying to achieve ? More like a test case for your smart pointer ...

Actually here's the code; it achieves reference counting (I hope!!!)
[...]
system("PAUSE") ;
return EXIT_SUCCESS;
}
It works apparently. Could you help me improve? Thanks!!!!
You could start by
1) not using platform dependent things like system("PAUSE") ;
2) using whitespace (indentation),
3) describing, what you want to improve.

Well, I don't think that it works, because your SmrtPtr<class holds a
SmrtPtrDB class (the ref counter) by value, while there should be only
one counter per object, shared by the smart pointers. Also, you should
handle operator=() by decrementing the count of the old object and
incrementing the new one.

--
Thomas
Jul 11 '06 #5

Thomas J. Gritzan wrote:
Protoman schrieb:
Gianni Mariani wrote:
Jon Rea wrote:
Protoman wrote:

OK, this code compiles, links, and executes, but, how do I setup, like,
a spinlock to query the DataBase object's status to let the SmrtPtr
know that the object's been deleted?:
It's very hard to understand what it is you're trying to do.

Could you write a snippet of code that describes more about what you're
trying to achieve ? More like a test case for your smart pointer ...
Actually here's the code; it achieves reference counting (I hope!!!)
[...]
system("PAUSE") ;
return EXIT_SUCCESS;
}
It works apparently. Could you help me improve? Thanks!!!!

You could start by
1) not using platform dependent things like system("PAUSE") ;
2) using whitespace (indentation),
3) describing, what you want to improve.

Well, I don't think that it works, because your SmrtPtr<class holds a
SmrtPtrDB class (the ref counter) by value, while there should be only
one counter per object, shared by the smart pointers. Also, you should
handle operator=() by decrementing the count of the old object and
incrementing the new one.

--
Thomas
Which one's the "old object", the one of the right side of operator=,
or the left side? And do you mean this:

SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
this->DataBase.sub() ;
delete ptr;
ptr(rhs.ptr);
rhs->DataBase.add() ;
}
else return this;
}

So, should DataBase be held by reference? And, system("PAUSE") is the
only way I can see my output, otherwise, the console opens and closes
before I get a chance to review. And I want to improve the handling of
the reference count; I don't think my impl is very effecient or
effective. And speed. And the handling of a null pointer, like if
someone writes:

SmrtPtr<intptr;

ptr will be initialized to null with my ctor, so deferencing it will be
illegal. I think it should throw an exception.

Jul 11 '06 #6
Protoman <Pr**********@g mail.comwrote:
And, system("PAUSE") is the
only way I can see my output, otherwise, the console opens and closes
before I get a chance to review.
A standards-compliant way to achieve a similar effect is:

std::cout << "\nPress <Enterto continue...\n";
std::string trash;
std::getline(st d::cin, trash);

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jul 12 '06 #7
Protoman schrieb:
Thomas J. Gritzan wrote:
>>It works apparently. Could you help me improve? Thanks!!!!
You could start by
1) not using platform dependent things like system("PAUSE") ;
2) using whitespace (indentation),
3) describing, what you want to improve.

Well, I don't think that it works, because your SmrtPtr<class holds a
SmrtPtrDB class (the ref counter) by value, while there should be only
one counter per object, shared by the smart pointers. Also, you should
handle operator=() by decrementing the count of the old object and
incrementing the new one.

Which one's the "old object", the one of the right side of operator=,
or the left side?
By assigning one smart pointer to another, you release the pointer on
the left hand side and copy the pointer from the right hand side to the
other.
So you have to decrement the lhs counter and increment the rhs counter.
But you must not delete the lhs pointer when the counter is not zero.
SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
this->DataBase.sub() ;
delete ptr;
Here you delete ptr. Don't do it when the counter is not zero.
ptr(rhs.ptr);
rhs->DataBase.add() ;
rhs is const and DataBase is private. This line should not work.
}
else return this;
}

So, should DataBase be held by reference?
By pointer. Look at the implementation of other smart pointers, like
shared_ptr from boost.

Buy a good C++ book and read it.
And, system("PAUSE") is the
only way I can see my output, otherwise, the console opens and closes
before I get a chance to review.
My IDE (Visual Studio) does this for me.

--
Thomas
Jul 12 '06 #8
Thomas J. Gritzan wrote:
By assigning one smart pointer to another, you release the pointer on
the left hand side and copy the pointer from the right hand side to the
other.
So you have to decrement the lhs counter and increment the rhs counter.
But you must not delete the lhs pointer when the counter is not zero.

>>SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs )
{
this->DataBase.sub() ;
delete ptr;

The standard way of doing this is to do a copy ctor on the source,
swap with the destination, and let the dtor for the local copy,
which is now the destination, run when it goes out of scope

SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs) {
SmrtPtr<Ttemp(r hs);
swap(temp);
return *this;
}

You're safe in the case of source and destination being the same
since the refcount will be incremented before it gets decremented.
--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software.
Jul 12 '06 #9

Joe Seigh wrote:
Thomas J. Gritzan wrote:
By assigning one smart pointer to another, you release the pointer on
the left hand side and copy the pointer from the right hand side to the
other.
So you have to decrement the lhs counter and increment the rhs counter.
But you must not delete the lhs pointer when the counter is not zero.

>SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rh s)
{
this->DataBase.sub() ;
delete ptr;

The standard way of doing this is to do a copy ctor on the source,
swap with the destination, and let the dtor for the local copy,
which is now the destination, run when it goes out of scope

SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs) {
SmrtPtr<Ttemp(r hs);
swap(temp);
return *this;
}

You're safe in the case of source and destination being the same
since the refcount will be incremented before it gets decremented.
--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software.
OK, here's the new SmrtPtr class:

// COPYRIGHT CMDR DOUGLAS I. PEREIRA 07/10/06
// ALL UNAUTHORIZED THIRD PARTY USE IS PROHIBITED
// I HAVE WORKED VERY HARD AND HAVE SPENT HOURS OF
// TIME DEVELOPING THIS. DO NOT COPY IT OR I WILL SUE YOU
// *************** *************** *************** ***************
#pragma once
#include <iostream>
#include "SmrtPtrDB. hpp"
using namespace std;
class NullPtr{};
template<class T>
class SmrtPtr
{
public:
explicit SmrtPtr<T>(T* obj=0):ptr(obj) , DataBase(new SmrtPtrDB){}
SmrtPtr<T>(cons t SmrtPtr<T>& rhs):ptr(rhs.pt r), DataBase(new
SmrtPtrDB(rhs.D ataBase->status())){Dat aBase->add();}
~SmrtPtr<T>()
{
DataBase->sub();
if(DataBase->status()==0)
{delete ptr;cout << "Deleted." << endl;}
else cout << "Out of scope. " << endl;
}
void operator=(T val){if(ptr==0) throw NullPtr();else *ptr=val;}
void operator=(T* val){ptr=val;}
SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
{
if(this!=&rhs)
{
SmrtPtr<Ttemp(r hs);
swap(temp);
}
else return *this;
}
bool operator==(cons t SmrtPtr<T>& rhs)const{if(pt r==rhs.ptr)retu rn
true;else return false;}
bool operator!=(cons t SmrtPtr<T>& rhs)const{if(pt r!=rhs.ptr)retu rn
true;else return false;}
bool operator<=(cons t SmrtPtr<T>& rhs)const{if(pt r<=rhs.ptr)retu rn
true;else return false;}
bool operator>=(cons t SmrtPtr<T>& rhs)const{if(pt r>=rhs.ptr)retu rn
true;else return false;}
int status(){return DataBase->status();}
T& operator*()cons t{if(ptr==0)thr ow NullPtr();else return *ptr;}
T* operator->()const{if(ptr ==0)throw NullPtr();else return ptr;}
operator T*()const{if(pt r==0)throw NullPtr();else return ptr;}
private:
void swap(SmrtPtr<T> & rhs){this=&rhs; }
mutable SmrtPtrDB* DataBase;
T* ptr;
};

Did I impl swap() correctly? Should DataBase be mutable?

Jul 13 '06 #10

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

Similar topics

6
2174
by: Elbert Lev | last post by:
Please correct me if I'm wrong. Python (as I understand) uses reference counting to determine when to delete the object. As soon as the object goes out of the scope it is deleted. Python does not use garbage collection (as Java does). So if the script runs a loop: for i in range(100): f = Obj(i)
1
2701
by: ash | last post by:
hi does anyone has any experience with flyweight pattern with refernce counting i want to share objects between multiple clients and want to delete the object from shared pool when the last client deletes a refernce to it
27
5944
by: Jason Heyes | last post by:
To my understanding, std::vector does not use reference counting to avoid the overhead of copying and initialisation. Where can I get a reference counted implementation of std::vector? Thanks.
0
1745
by: Kalle Rutanen | last post by:
Hello I implemented reference counting in my program, and found out many problems associated with it. I wonder if the following problems can be solved automatically rather manually ? 1. In its member function, an object manages to destroy last reference to itself and thus destructs before the end of the member function.
1
3247
by: Tony Johansson | last post by:
Hello Experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don't understand completely. It says "A garbarage collector, such as the one used in Java, maintains a record of whether or not an object is currentlys being used. An unused object is tagged as garbage,
1
1873
by: Tony Johansson | last post by:
Hello Experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don't understand completely. It says "A garbarage collector, such as the one used in Java, maintains a record of whether or not an object is currentlys being used. An unused object is tagged as garbage,
4
4191
by: aaronfude | last post by:
Hi, Please consider the following class (it's not really my class, but it's a good example for my question): class Vector { int myN; double *myX; Vector(int n) : myN(n), myX(new double) { } double &operator()(int i) { return myX; }
1
2271
by: oec.deepak | last post by:
Hi Cn any one telll me what is Reference counting in C++.
8
1854
by: mathieu | last post by:
Hi there I have implemented a very simple smartpointer class (invasive design). And I was wondering what should be the natural API when using those in a Container. I choose to define the following operator in my smartpointer class: .... operator ObjectType * () const
275
12233
by: Astley Le Jasper | last post by:
Sorry for the numpty question ... How do you find the reference name of an object? So if i have this bob = modulename.objectname() how do i find that the name is 'bob'
0
8189
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8694
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8635
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8497
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7184
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5570
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4089
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4193
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1803
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.