Skip to content

Instantly share code, notes, and snippets.

@raghunayak
Last active February 27, 2022 08:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raghunayak/880614be3353e09ccba5 to your computer and use it in GitHub Desktop.
Save raghunayak/880614be3353e09ccba5 to your computer and use it in GitHub Desktop.
A simple shared_ptr example.
/*
* Simple implementation of shared_ptr.
* Below code is non thread safe.
*
* (c) 2015 Raghavendra Nayak, All Rights Reserved.
* http://www.openguru.com/
*/
#include <iostream>
namespace my {
template <class T>
class shared_ptr {
T* ptr;
int* ref_count;
/**
* Initializes the ref count used for tracking the usage.
*/
void initialize_ref_count() {
if (ref_count != nullptr)
return;
try {
ref_count = new int;
*ref_count = 1;
}
catch (std::bad_alloc& e) {
std::cerr << "Memory allocation error: " << e.what();
}
}
public:
// Constructors
shared_ptr()
: ptr(nullptr), ref_count(nullptr) {}
shared_ptr(nullptr_t ptr)
: ptr(ptr), ref_count(nullptr) {
}
shared_ptr(T* ptr)
: ptr(ptr), ref_count(nullptr) {
initialize_ref_count();
}
// Destructor
~shared_ptr() {
--(*ref_count);
if (*ref_count == 0) {
delete ref_count;
ref_count = nullptr;
delete ptr;
ptr = nullptr;
}
}
// Copy constructor
shared_ptr(const shared_ptr& copy) {
ptr = copy.ptr;
ref_count = copy.ref_count;
if (ref_count != nullptr) {
++(*ref_count);
}
}
// Assignment operator
shared_ptr& operator=(const shared_ptr& copy) {
ptr = copy.ptr;
ref_count = copy.ref_count;
if (ref_count != nullptr) {
++(*ref_count);
}
return *this;
}
// Returns stored object reference
T& operator*() const {
return *ptr;
}
// Returns stored object pointer
T* operator->() const {
return ptr;
}
};
}
class Base
{
int data;
public:
Base() : data(0) { std::cout << " Base::Base()\n"; }
virtual ~Base() { std::cout << " Base::~Base()\n"; }
void set_data(int data) {
this->data = data;
}
int get_data() const {
return this->data;
}
};
class Derived : public Base
{
public:
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
my::shared_ptr<Base> function()
{
my::shared_ptr<Base> ptr = new Derived();
return ptr;
}
int main(int argc, char **argv)
{
// Default constructor
my::shared_ptr<Base> ptr1;
{
// Parameterized constructor
my::shared_ptr<Base> ptr2 = function();
// operator function call
ptr2->set_data(100);
// copy constructor call
my::shared_ptr<Base> ptr3 = ptr2;
// assignment operator call
ptr1 = ptr3;
}
// operator function call
std::cout << " data set to: " << (*ptr1).get_data() << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment