Skip to content

Instantly share code, notes, and snippets.

@jakab922
Last active April 22, 2020 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakab922/e3b906e7438be7851109c08364696585 to your computer and use it in GitHub Desktop.
Save jakab922/e3b906e7438be7851109c08364696585 to your computer and use it in GitHub Desktop.
C++ smart pointer implementation
#include <bits/stdc++.h>
using namespace std;
template <typename T>
class my_shared_ptr {
T *data;
int *ref_count;
void _possibly_destroy() {
if (*ref_count == 0) {
delete data;
delete ref_count;
data = nullptr;
ref_count = nullptr;
}
}
public:
my_shared_ptr() : data{nullptr}, ref_count{nullptr} {}
my_shared_ptr(T *_data) : data{_data}, ref_count{new int{1}} {}
// copy constructor
my_shared_ptr(const my_shared_ptr<T> &other) {
data = other.data;
ref_count = other.ref_count;
(*ref_count)++;
}
// copy assignment operator
my_shared_ptr<T> &operator=(const my_shared_ptr<T> &other) {
if (other.data == data) return *this;
(*ref_count)--;
_possibly_destroy();
data = other.data;
ref_count = other.ref_count;
(*ref_count)++;
return *this;
}
//move constructor
my_shared_ptr(my_shared_ptr<T> &&other) {
data = other.data;
ref_count = other.ref_count;
other.reset();
}
// move assignment operator
my_shared_ptr<T> &operator=(my_shared_ptr<T> &&other) {
(*ref_count)--;
_possibly_destroy();
data = other.data;
ref_count = other.ref_count;
other.reset();
return *this;
}
~my_shared_ptr() {
if (ref_count == nullptr) return; // If it was resetted there isn't much to do here.
(*ref_count)--;
_possibly_destroy();
}
size_t use_count() const {
return *ref_count;
}
T *get() {
return data;
}
void reset() {
data = nullptr;
ref_count = nullptr;
}
};
int main() {
cout << "normal constructor" << endl;
my_shared_ptr<int> one{new int{1}}; // normal constructor
cout << "one.use_count(): " << one.use_count() << endl; // should be 1
cout << endl
<< "copy constructor" << endl;
my_shared_ptr<int> other{one}; // copy constructor;
cout << "one.use_count(): " << one.use_count() << endl; // should be 2
cout << "other.use_count(): " << other.use_count() << endl; // should also be 2
assert(one.get() == other.get()); // They should point to the same object
cout << endl
<< "move constructor" << endl;
my_shared_ptr<int> third{my_shared_ptr<int>{new int{1}}}; // move constructor
cout << "third.use_count(): " << third.use_count() << endl; // should be 1
assert(third.get() != nullptr); // Should point somewhere
cout << endl
<< "copy assignment" << endl;
other = third; // copy assignment operator
cout << "one.use_count(): " << one.use_count() << endl; // should be 1
cout << "other.use_count(): " << other.use_count() << endl; // should be 2
cout << "third.use_count(): " << third.use_count() << endl; // should be 2
assert(other.get() == third.get() && one.get() != other.get());
cout << endl
<< "move assignment first version" << endl;
one = my_shared_ptr<int>{new int{1}}; // Move assignment version 1
cout << "one.use_count(): " << one.use_count() << endl; // should be 1
cout << endl
<< "move assignment second version" << endl;
one = move(third); // Move assignment second case
cout << "one.use_count(): " << one.use_count() << endl; // Should be 2
cout << "other.use_count(): " << other.use_count() << endl; // Should be 2
assert(one.get() == other.get() && third.get() == nullptr);
my_shared_ptr<int> fourth;
assert(fourth.get() == nullptr);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment