I am writing a c++11+ standards compliant class, and it is time for me to implement the rule of 5.
- Destructor
- Copy Constructor
- Move Constructor
- Copy Assignment Operator
- Move Assignment Operator
I had a question about copy/move constructors/assignment. It is my understanding that a copy constructor/assignment should make a copy (shallow, deep?) of your class. In the case that your class has unique members, such as a unique_ptr, there are two scenarios I foresee.
Make a deep copy of the object
I am not sure, in my case, how I would make a deep copy (see code below).
Move the object to the other class
In my opinion, moving the pointer in a copy constructor has unintended side effects for a user, as they are expecting a copy, and not a move, and the original object being copied would no longer function.
Making a copy could also be problematic, however, in my case, the curl object could contain sensitive information such as cookies or a password?
What is the defacto way to create copy and move constructors/assignment for classes with these constraints? To deep copy, to move, or not explicitly and implicitly define a copy constructor (does the delete keyword do this)?
// client.h
#pragma once
#include <Poco/URI.h>
#include <curl/curl.h>
class client
{
public:
typedef Poco::URI uri_type;
// Constructor
client(const uri_type & auth);
// Destructor
virtual ~client();
// Copy constructor
client(const client & other);
// Move constructor
client(client && other);
// Copy assignment
client & operator=(const client & other);
// Move assignment operator
client & operator=(client && other);
private:
uri_type auth_;
// ... other variables (both unique and copyable) ommitted for simplicity.
std::unique_ptr<CURL, void(*)(CURL*)> ptr_curl_;
};
// client.cpp
#include <memory>
#include <Poco/URI.h>
#include <curl/curl.h>
#include "client.h"
// Constructor
client::client(const uri_type & auth)
: auth_(auth)
, ptr_curl_(curl_easy_init(), curl_easy_cleanup)
{
curl_global_init(CURL_GLOBAL_DEFAULT);
}
// Destructor
client::~client()
{
curl_global_cleanup();
}
// Copy constructor
client::client(const client & other)
{
// ... deep copy? move?
// how would you deep copy a unique_ptr<CURL>?
}
// Move constructor
client::client(client && other)
{
std::swap(*this, other);
}
// Copy assignment
client & client::operator=(const client & other)
{
// Cant get this to work by making the copy happen in the parameter.
client temp(other);
std::swap(*this, temp);
return *this;
}
// Move assignment operator
client & client::operator=(client && other)
{
return *this;
}