#include <iostream>
using namespace std;
template<typename T>
class sharedptr{
private:
T *res;
T *counter;
void incrementcounter()
{
if(counter)
{
(*counter)++;
}
}
void decrementcounter()
{
if(counter)
{
(*counter)--; now while decrementing the counter what if counter become zero then we need delte it .
if(*(counter) == 0) // here we check if the counter is zero we will delete the resource and counter
{
if(res) //just to check if there is any res
{
delete res;
delete counter;
res = nullptr;
}
}
}
}
public:
shareptr(T* ptr=nullptr) : res(ptr) , counter(new int(1)) // means everytime somebody calls we calls counter is taken as 1
{
cout<<"constructor called";
}
shareptr<T>(const shareptr<T>& ptr) //now copy construtor will come when we write this. 2 resource will point to same place
{
res=ptr.res; //both ptr2 nd ptr3 is pointing to the same resource
couunter = ptr.counter; // similarly with counter, whatever pointing to the ptr counter same is pointing to current counter
incrementcounter(); // and also we need to increment the counter so for that we need to call a function which we will declare in private scope. cz no other member needs to use it
// as we need the fucntion is other places also we need also have multiple statement so we use a sepatrate fcuntion
}
//when we do ptr3=ptr2 so ptr2 is pointing to some resource and ptr3 is pointing to some other resource now we need to make them point to same resource
// so basically for this we need to decrement the pointer for ptr3 and point to ptr2 and then increment the counter
shareptr<T>& operator=(const shareptr<T>& ptr) //copy assignment operator
{
if(this != &ptr)
{
decrementcounter(); //as all the checks are happening within the function so we no need to write it here
// supoose after decrementing this object was the only one pointing to that resource counter would have become 0 so we delte that resource
res = ptr.res;
counter = ptr.counter; // now whatever ptr counter came it will point to same counter.
incrementcounter(); // no we increment the counter
}
return *this;
}
shareptr<T>(shareptr<T> && ptr) // move copy construtcor , here we dont need const cz we are changing the ptr itseelf
{
res = ptr.res; // ptr will point to res
counter = ptr.counter; //counter will point to this counter
//we take the whole resource and pass to another and current to null. but do we need increment counter??
//no , the counter is same because earlier another pointer was coming so we were incrementing the counter
// but here there is totally a new pointer where we transfer the ownership so we need the same count as prev counter
ptr.res = nullptr;
ptr.counter = nullptr;
}
shareptr<T>& operator=(shareptr<T>&& ptr) //move copy assignment operator
{
if(this != &ptr)
{
decrementcounter(); // decrement the counter because now we will be pointing to something else this which was pointing to we have to decrememt
// cz in case of constructor we dont point to somthing but as it is copy assignment we are already pointing to something so we need to decrememt
res = ptr.res;
counter = ptr.counter; // here new pointer is pointing to where old ptr was pointing and old one we make it null cz we are trasfering
ptr.res = nullptr;
ptr.counter = nullptr;
}
return *this;
}
void reset(T* ptr) // one obj is already trying to point to something now we are trying to reset to some other new resource
{
decrementcounter(); //as this obj is already pointing now this will be leaving the what it points to . so we neeed to decrement the counter
res= ptr.res; // then pouint to new res , so it need to create a counter all toghether it cannot use the same counter
counter = new int(1); // so we are reseting the counter to 1 . this is new fresh one
}
int get_count()
{
if(counter)
{
return (*counter);
}
return -1;
}
T* operator->()
{
return res;
}
T& operator*()
{
return (*res);
}
T* get()
{
return res;
}
~shareptr() // when this ptr goes out of scope so whatever the this object is pointing the resource to it should decrement the count not delete it
{ // cz it might be pointed out by some other obj.
decrementcounter(); // so inside decrementcounter function it will take care in a sense means if its a last ptr when count becomes 0 then it should delete it
}
};
int main() {
shareptr<int> ptr1; //default constructor
shareptr<int> ptr2(new int(10)); //param constructor
shareptr<int> ptr3(ptr2); //copy const
shareptr<int> ptr4(new int(40)); //copy assignment operator
ptr4 = ptr3;
sharedptr<int> ptr4(move(ptr1));//ownership is transferrred from ptr1 to the new ptr that is ptr4 . how this gets implemented . this gets implemented using move copy constructor.
ptr2 = move(ptr3); //move copy assignment operator
APIs that can be used
ptr1.reset(); it will reset to null
ptr1.reset(new int(5)); // it will reset with some resource.
ptr1->func(); // implementing -> operator
cout<<*ptr1; //inplementing * operator
ptr1.get() // it returns the raw pointer
//here we need to implmenet one more thing which was not present in unique ptr
ptr1.get_count() //shared ptr will be use for multiple resources so get count api is implemented. no of object pointing to the same resoource
return 0;
}
To embed this project on your website, copy the following code and paste it into your website's HTML: