C++ 规则 5 复制和 move (构造函数和赋值)警告 : to copy or move

标签 c++ move copy-constructor

我正在编写一个符合 c++11+ 标准的类,现在是我实现规则 5 的时候了。

  1. Destructor
  2. Copy Constructor
  3. Move Constructor
  4. Copy Assignment Operator
  5. Move Assignment Operator

我有一个关于复制/move 构造函数/赋值的问题。据我了解,复制构造函数/赋值应该复制(浅,深?)你的类(class)。如果您的类具有唯一成员,例如 unique_ptr,我预见到两种情况。

  • 对对象进行深拷贝

    在我的情况下,我不确定如何制作深拷贝(请参阅下面的代码)。

  • 将对象 move 到其他类

    在我看来,在复制构造函数中 move 指针会对用户产生意想不到的副作用,因为他们期待的是复制,而不是 move ,并且被复制的原始对象将不再起作用。

    制作拷贝也可能有问题,但是,在我的情况下,curl 对象可能包含敏感信息,例如 cookie 或密码?


为具有这些约束的类创建复制和 move 构造函数/赋值的实际方法是什么?要深拷贝、 move ,还是不显式和隐式定义复制构造函数(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;
}

最佳答案

顾名思义,复制构造函数/赋值运算符应该始终复制而不是 move 其成员,其中复制通常表示深复制。

记住:默认情况下,c++ 中的所有对象都应该具有值语义,即它们的行为应该像 int

此外,您帖子中的术语表明您将唯一对象(单例)与 unique_ptr 指向的对象混淆了。大多数不可复制的对象都是处理程序(如 unique_ptr 处理堆上的对象),在这种情况下,您将复制它们处理的任何内容。如果那不可能,那么很可能实现对象的复制构造函数根本没有意义。

如果您的对象持有对唯一资源的拥有引用(您的项目中只能有一个实例),那么第一个问题是:它可以共享吗? -> 使用 shared_ptr。如果不是 -> 不要复制。 如果您的对象持有对唯一资源(原始指针或引用)的非拥有引用,请复制该引用。在这两种情况下,请注意您现在有两个对象,它们共享它们的部分状态,即使在非多线程应用程序中,这也可能是危险的。

关于C++ 规则 5 复制和 move (构造函数和赋值)警告 : to copy or move,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29465527/

相关文章:

c++ - 没有指针数据成员的类 - 复制构造函数 == 赋值运算符?

c++ - 为什么for_each通过move返回函数

Java eclipse 路径文件可执行文件

css - 将鼠标移到社交图标上时如何更改它们的颜色?

c++ - 动态分配对象数组

c++ - 为什么 int ia2[10] 的默认值为 0,即使它是在函数内部定义的?

C++ win32 设置光标位置

c++ - OpenGL - 从 DisplayList 转换为使用 VBO

c++ - 在 C++ 中将值从字符串输入到 wchar 变量

c++ - 为什么这里不调用拷贝构造函数?