Suppose I want to implement a class which is copyable, so I can implement the copy constructor and assignment operator. However, what is the correct implementation and handling of unique and shared pointer variables? See this contrived example which has both types of pointers:
Header File
#include <memory>
using std::unique_ptr;
using std::shared_ptr;
class Copyable
{
private:
unique_ptr<int> uniquePointer;
shared_ptr<int> sharedPointer;
public:
Copyable();
Copyable(int value);
Copyable(const Copyable& other);
~Copyable();
public:
int GetUniqueValue() { return *uniquePointer; };
int GetSharedValue() { return *sharedPointer; };
Copyable& operator=(const Copyable& other);
};
CPP File
#include "stdafx.h"
#include "Copyable.h"
using namespace std;
Copyable::Copyable() :
uniquePointer(make_unique<int>()), sharedPointer(make_shared<int>())
{
}
Copyable::Copyable(int value) :
uniquePointer(make_unique<int>(value)),
sharedPointer(make_shared<int>(value))
{
}
Copyable::Copyable(const Copyable& other) :
uniquePointer(make_unique<int>(*other.uniquePointer)),
sharedPointer(make_shared<int>(*other.sharedPointer))
// OR
sharedPointer(other.sharedPointer)
{
}
Copyable::~Copyable()
{
}
Copyable& Copyable::operator=(const Copyable& other)
{
if (&other != this)
{
uniquePointer.reset();
uniquePointer = make_unique<int>(*other.uniquePointer);
sharedPointer = make_shared<int>(*other.sharedPointer);
// OR
sharedPointer = other.sharedPointer;
}
return *this;
}
Usage Allows Copying
Copyable copyable1(5);
int uniqueValue1 = copyable1.GetUniqueValue();
int sharedValue1 = copyable1.GetSharedValue();
Copyable copyable2 = copyable1;
int uniqueValue2 = copyable2.GetSharedValue();
int sharedValue2 = copyable2.GetSharedValue();
There is only one way to copy the unique pointer using the make_unique function but what about the shared pointer? Should I assign it or use the make_shared function?
UPDATE - Copying versus Moving
One a wider note I'm trying to figure out when to use what. If I decide to use copying, why would I use unique_ptr? It seems shared_ptr is the way to go. Equally, if using move semantics, unique_ptr seems the way to go. Generally speaking only. I should perhaps split this into a separate question.