5复制和移动(构造函数和赋值)的C ++规则警告:复制或移动 [英] C++ Rule of 5 copy and move (constructor and assignment) caveat: to copy or move

查看:87
本文介绍了5复制和移动(构造函数和赋值)的C ++规则警告:复制或移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a c++11+ standards compliant class, and it is time for me to implement the rule of 5.

  1. 析构函数
  2. 复制构造器
  3. 移动构造器
  4. 复制分配运算符
  5. 移动分配运算符
  1. Destructor
  2. Copy Constructor
  3. Move Constructor
  4. Copy Assignment Operator
  5. Move Assignment Operator


我对复制/移动构造函数/分配有疑问.我的理解是,复制构造函数/赋值应该制作类的副本(浅,深?).如果您的班级有唯一的成员,例如unique_ptr,我预见有两种情况.


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).

将对象移动到另一个类

我认为,在复制构造函数中移动指针会对用户产生意想不到的副作用,因为他们期望复制,而不是移动,并且复制的原始对象将不再起作用.

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.

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

Making a copy could also be problematic, however, in my case, the curl object could contain sensitive information such as cookies or a password?

为具有这些约束的类创建复制并移动构造函数/赋值的实际方法是什么?要深层复制,移动或不显式和隐式定义复制构造函数(执行delete关键字这样)?

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;
}

推荐答案

顾名思义,复制构造函数/赋值运算符应始终COPY而不移动其成员,复制通常表示深层复制.

As the name indicates, a copy constructor/assignment operator should always COPY and not move its members, where copy usually means deep copy.

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

Remember: By default, all objects in c++ should have value semantics, i.e. they should behave like an int.

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

Furthermore, the terminology in your post indicates that you are confusing unique objects (singletons) with objects pointed to by unique_ptr. Most non-copyable objects are handlers (like unique_ptr handles objects on the heap) in which case you'd copy whatever they handle. If that is not possible, then most likely, it doesn't make sense to implement a copy constructor of your object at all.

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

If your object holds an owning reference to a unique resource (from which there can be only one instance in your project),then the first question would be: can it be shared? -> use shared_ptr. If not -> don't copy. If your object holds a non-owning reference to a unique ressource (raw pointer or reference) copy the reference. In both cases, be aware that you now have two objects, that share part of their state, which might be dangerous even in non-multithreaded applications.

这篇关于5复制和移动(构造函数和赋值)的C ++规则警告:复制或移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆