问题
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.
回答1:
What about the shared pointer? Should I assign it or use the make_shared function?
tl;dr The assignment is most likely what you are looking for.
This depends entirely on the semantics of the class involved;
- If you want the objects to share the state of the
shared_ptr
then an assignment or a copy would be required - If you want each object to maintain it's own state, then create a new
shared_ptr
based on the "other" object
If the shared state it not required, you really are just better off with a unique_ptr
As a general "rule of thumb";
If your type contains move only members, then only allow moving. If your type has copyable members, allow copying. Where it makes sense, follow the "value" type semantics. Strive for the "rule of zero"
来源:https://stackoverflow.com/questions/24890215/proper-implementation-of-copy-constructor-and-equals-operator-on-a-class-with-sm