#include <iostream>
using
namespace
std;
class
Counter
{
public
:
Counter()
: m_counter(0){};
Counter(
const
Counter&) =
delete
;
Counter& operator=(
const
Counter&) =
delete
;
~Counter() {}
void
reset()
{
m_counter = 0;
}
unsigned
int
get()
{
return
m_counter;
}
void
operator++()
{
m_counter++;
}
void
operator++(
int
)
{
m_counter++;
}
void
operator--()
{
m_counter--;
}
void
operator--(
int
)
{
m_counter--;
}
friend
ostream& operator<<(ostream& os,
const
Counter& counter)
{
os <<
"Counter Value : "
<< counter.m_counter
<< endl;
return
os;
}
private
:
unsigned
int
m_counter{};
};
template
<
typename
T>
class
Shared_ptr
{
public
:
explicit
Shared_ptr(T* ptr = nullptr)
{
m_ptr = ptr;
m_counter =
new
Counter();
(*m_counter)++;
}
Shared_ptr(Shared_ptr<T>& sp)
{
m_ptr = sp.m_ptr;
m_counter = sp.m_counter;
(*m_counter)++;
}
unsigned
int
use_count()
{
return
m_counter->get();
}
T* get()
{
return
m_ptr;
}
T& operator*()
{
return
*m_ptr;
}
T* operator->()
{
return
m_ptr;
}
~Shared_ptr()
{
(*m_counter)--;
if
(m_counter->get() == 0)
{
delete
m_counter;
delete
m_ptr;
}
}
friend
ostream& operator<<(ostream& os,
Shared_ptr<T>& sp)
{
os <<
"Address pointed : "
<< sp.get() << endl;
os << *(sp.m_counter) << endl;
return
os;
}
private
:
Counter* m_counter;
T* m_ptr;
};
int
main()
{
Shared_ptr<
int
> ptr1(
new
int
(151));
cout <<
"--- Shared pointers ptr1 ---\n"
;
*ptr1 = 100;
cout <<
" ptr1's value now: "
<< *ptr1 << endl;
cout << ptr1;
{
Shared_ptr<
int
> ptr2 = ptr1;
cout <<
"--- Shared pointers ptr1, ptr2 ---\n"
;
cout << ptr1;
cout << ptr2;
{
Shared_ptr<
int
> ptr3(ptr2);
cout <<
"--- Shared pointers ptr1, ptr2, ptr3 "
"---\n"
;
cout << ptr1;
cout << ptr2;
cout << ptr3;
}
cout <<
"--- Shared pointers ptr1, ptr2 ---\n"
;
cout << ptr1;
cout << ptr2;
}
cout <<
"--- Shared pointers ptr1 ---\n"
;
cout << ptr1;
return
0;
}