当前位置: 首页 > 知识库问答 >
问题:

生成复制和移动运算符?

姜嘉赐
2023-03-14

目前我读了Scott Meyers有效现代C一书,现在我在:第17项:理解特殊成员函数的生成。

我的误解来自以下部分(理由):

这两个复制操作是独立的:声明一个并不会阻止编译器生成另一个。因此,如果您声明了复制构造函数,但没有复制赋值操作符,然后编写需要复制赋值的代码,编译器将为您生成复制赋值操作符。类似地,如果您声明了复制赋值操作符,但没有复制构造函数,但代码需要复制构造,编译器将为您生成复制构造函数。这在C98中是正确的,在C11中仍然是正确的。

这两个移动操作不是独立的。如果声明其中一个,则会阻止编译器生成另一个。基本原理是,如果你为你的类声明了一个move构造函数,你是在表明应该如何实现move构造,这与编译器生成的默认memberwise move不同。如果memberwise移动构造有问题,那么memberwise移动赋值也可能有问题。因此,声明移动构造函数会阻止生成移动赋值运算符,而声明移动赋值运算符会阻止编译器生成移动构造函数

我认为基本原理部分也可以应用于复制构造函数复制赋值运算符对,不是吗?因此,如果我声明了一个复制构造函数,我会用它指出默认的memberwise复制对我来说是不够的。如果我这么说的话,那么复制赋值操作符也应该是用户定义的。

我认为这是一本伟大的书,但在这一点上,我不清楚这个理由。请帮我解释一下。谢谢。


共有1个答案

冯通
2023-03-14

我认为基本原理部分也可以应用于复制构造函数和复制赋值运算符对,不是吗?

绝对地这个标准符合你的要求。在[class.copy]中:

如果类定义没有显式声明副本构造函数,则隐式声明非显式构造函数。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。

以及:

如果类定义没有显式声明复制赋值操作符,则隐式声明一个。如果类定义声明了移动构造函数或移动赋值操作符,隐式声明的复制赋值操作符被定义为删除;否则,它被定义为默认(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不建议使用后一种情况。

当然,如果“后一种情况”被立即废除,可能会有很多现有的代码被破坏,这就是为什么标准首先弃用,并且只会在未来某个任意遥远的时刻删除它们。

话说回来,即使是长期被弃用和删除的功能,也有一种在不受欢迎的情况下徘徊的方式。像char*s="MyString";

 类似资料:
  • 本文向大家介绍详解C++中对构造函数和赋值运算符的复制和移动操作,包括了详解C++中对构造函数和赋值运算符的复制和移动操作的使用技巧和注意事项,需要的朋友参考一下 复制构造函数和复制赋值运算符 从 C++ 11 中开始,该语言支持两种类型的分配:复制赋值和移动赋值。 在本文中,“赋值”意味着复制赋值,除非有其他显式声明。 赋值操作和初始化操作都会导致对象被复制。 赋值:在将一个对象的值赋给另一个对

  • 在我的国际象棋引擎中,它使用比特板来表示棋盘的状态,一次生成一大块伪合法的棋步,结果就是一个比特板。例如: 典当: 稍后有点比特板魔术: 末尾的位板只是一大块可能的移动。引擎通常如何使用这个位板并从中生成单独的移动?我是否必须遍历每一位来检查它是否设置好?不过,在位板上迭代似乎违背了使用位板的目的,这就是为什么我有点怀疑。 有更好的办法吗?

  • Entry和FileEntry均有copyTo和moveTo方法用来复制和移动目录和文件。 Entry.copyTo(newEntry, 'new_Entry_name', function(copiedEntry){ console.log('Entry moved.'); }, errorHandler); Entry.moveTo(newEntry, 'new_Entry_name

  • 有没有办法用三元运算来实现这个。我对三进制很陌生,也许你可以指导我。 这个好像不行。

  • 这是一个关于如何使用魔法棋盘在国际象棋中验证滑动棋子移动的大局的问题。我只是想澄清一下,我不是在问魔法比特板在内部是如何工作的。 现在,关于这个问题的更多细节。我正在使用位板编写棋盘表示,我想使用魔术位板验证滑块移动。有人能列出如何实现这一目标的主要步骤吗?作为一个例子,考虑以下棋盘位置: 假设我们已经初始化并准备好使用所有魔术位板函数和数据结构。因此,仅使用魔法比特板的函数签名,您能否列出验证g

  • 问题 你想要复制或移动文件和目录,但是又不想调用shell命令。 解决方案 shutil 模块有很多便捷的函数可以复制文件和目录。使用起来非常简单,比如: import shutil # Copy src to dst. (cp src dst) shutil.copy(src, dst) # Copy files, but preserve metadata (cp -p src dst)