最简洁的方法禁用复制类在C + + 11 [英] Most concise way to disable copying class in C++11

查看:149
本文介绍了最简洁的方法禁用复制类在C + + 11的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题处理已弃用,因为C ++ 11默认生成复制构造函数和复制赋值运算符,当有一个用户定义的析构函数。

I have a problem dealing with deprecated since C++11 default generation of copy constructor and copy assignment operator when there is a user-defined destructor.

对于大多数足够简单的类默认生成的构造函数,运算符和析构函数都很好。请考虑以下原因声明析构函数:

For most sufficiently simple classes default-generated constructors, operators and destructor are fine. Consider the following reasons to declare destructor:


  1. 在基类中创建虚拟析构函数:

  1. Making trivial destructor virtual in base class:

// header
class Base1 { public: virtual ~Base1() = default; };
class Base2 { public: virtual ~Base2(); };
// source
Base2::~Base2() = default;

在这些情况下,所有4个复制和移动特殊方法是否都由编译器生成?如果是,那么我认为这是很好,没有必要复杂 Base1 Base2

Would all 4 copy and move special methods be generated by compiler in these cases? If yes, then I think it is fine and there is no need to complicate Base1 or Base2.

在析构函数中打印调试消息:

Printing debug message in destructor:

// header
class D { public: ~D(); };
// source
D::~D() {
#ifdef DEBUG_THIS
    std::cout << "D was destructed." << std::endl;
#endif
}



我相信在这种情况下复制构造函数和赋值运算符;但是移动构造函数和赋值运算符不会。我想避免使用已弃用的默认生成并禁用复制 D 。我也想避免洪水 D 与4 删除声明。只禁用一个副本构造函数足够?

I believe that in this case copy constructor and assignment operator would be generated; but move constructor and assignment operator would not. I want to avoid using deprecated default-generating and disable copying of D. I also want to avoid flooding D with 4 deleted declarations. Is disabling only one copy constructor enough? Is it a good style?


推荐答案


  1. 当析构函数显式默认时,只会生成复制构造函数和复制赋值操作符。即使那样,他们的一代也被弃用了。所以,为了有虚拟析构函数和所有的默认方法,应该写如下:

  1. Only copy constructor and copy assignment operator will be generated when destructor is explicitly defaulted. And even then their generation is deprecated. So, in order to have virtual destructor and all default methods, one should write the following:

struct Base
{
    Base()=default;
    virtual ~Base() = default;
    Base(const Base&)=default;
    Base& operator=(const Base&)=default;
    Base(Base&&)=default;
    Base& operator=(Base&&)=default;
};

我肯定会使用一个以上的宏 Base class。

I would definitely use a macro for more than one such Base class.

如果用户定义析构函数 ,还会生成两个特殊方法。有以下方法可以禁用已弃用的生成复制构造函数和复制赋值运算符:

In case when destructor is defined by user, 2 special methods are still generated. There are the following ways to disable deprecated generating copy constructor and copy assignment operator:


  • 构造函数或移动赋值操作符(不完全自我解释,但非常短):
  • delete move constructor OR move assignment operator (not quite self-explanatory but very short):

Base(Base&&)=delete; // shorter than deleting assignment operator


  • 和复制赋值运算符:

  • delete both copy constructor and copy assignment operator:

    Base(const Base&)=delete;
    Base& operator=(const Base&)=delete;
    


  • 注意,你必须显式声明默认构造函数如果你需要它,eg Base()= default;

    Note that you have to explicitly declare default constructor if you need it, e.g. Base()=default;.

    宏或继承特殊类也可用于此目的,个人更喜欢删除移动构造函数来实现我自己的宏或基类。使用 Qt boost 时,我宁愿使用 Q_DISABLE_COPY(Base) :noncopyable ,因为它们已经实现,广为人知和可识别。

    Macro or inheriting special class can be used as well for this purpose but I personally prefer deleting move constructor to implementing my own macro or base class. When using Qt or boost, I would prefer Q_DISABLE_COPY(Base) and inheriting boost::noncopyable respectively, because they are already implemented, widely known and recognizable.

    a href =http://accu.org/index.php/journals/1896 =nofollow> http://accu.org/index.php/journals/1896 - 详细说明和原因对于这些问题。

    http://accu.org/index.php/journals/1896 - detailed explanation and rationale for these issues.

    这篇关于最简洁的方法禁用复制类在C + + 11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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