具有移动语义的RAII类中的默认构造函数应该做什么?

克洛菲

移动语义对于RAII类非常有用。它们允许人们进行编程,就好像一个人具有有价值的语义,而无需付出繁重的工作。一个很好的例子是从一个函数返回std :: vector但是,使用值语义进行编程意味着,人们希望类型表现得像原始数据类型一样。有时这两个方面似乎是矛盾的。

一方面,在RAII中,人们会期望默认构造函数返回完全初始化的对象,或者如果资源获取失败则抛出异常。这保证了任何构造的对象都将处于有效且一致的状态(即可以安全使用)。

另一方面,使用移动语义时,存在对象处于有效但未指定状态的情况同样,原始数据类型可以处于未初始化状态。因此,使用值语义,我希望默认构造函数在此有效但未指定的状态下创建一个对象,以便以下代码具有预期的行为:

// Primitive Data Type, Value Semantics
int i;
i = 5;

// RAII Class, Move Semantics
Resource r;
r = Resource{/*...*/}

在这两种情况下,我都希望“大量”初始化仅发生一次。我想知道,关于此的最佳做法是什么?显然,第二种方法存在一个实际的问题:如果默认构造函数以未指定状态创建对象,那么如何编写一个确实可以获取资源但不带有其他参数的构造函数呢?(想到了标签分派...)

编辑:一些答案对试图使您的类像原始数据类型一样工作的理由提出了质疑。我的一些动力来自Alexander Stepanov的《带组件的高效编程》,他在其中谈论了常规类型。特别地,让我引用:

在c中[对于内置类型],自然的惯用语表达应该是对于常规类型的自然的惯用语表达。

他继续提供与上述几乎相同的示例。在这种情况下他的观点无效吗?我理解不对吗?

编辑:由于没有太多讨论,我将接受投票率最高的答案。在默认构造函数中以“ moved-from like”状态初始化对象可能不是一个好主意,因为同意现有答案的每个人都不会期望这种行为。

本杰明·林德利(Benjamin Lindley)

但是,使用值语义进行编程意味着,人们希望类型表现得像原始数据类型一样。

关键字“喜欢”。不是“相同地”。

因此,使用值语义,我希望默认构造函数在此有效但未指定的状态下创建一个对象

我真的不明白为什么您应该期望这一点。对我来说,这似乎不是一个非常理想的功能。

关于此的最佳实践是什么?

忘记这样一个想法,即非POD类应该与原始数据类型共享此功能。头错了。如果没有明智的方法来初始化没有参数的类,则该类不应具有默认构造函数。

如果您想声明一个对象,但不愿初始化它(可能在更深的范围内),请使用std::unique_ptr

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有移动构造函数和分配的类的默认副本构造函数和分配

来自分类Dev

在一个类中,“使用Base :: BaseOfBase;”应该做什么?

来自分类Dev

另一个类的移动构造函数中的移动类(没有默认构造函数)

来自分类Dev

netbeans中的Watch进程选项应该做什么?

来自分类Dev

'{default:'1}在系统Verilog中应该做什么?

来自分类Dev

Material-UI中的notched属性应该做什么

来自分类Dev

Vis.js中的“ horizontalScroll”选项应该做什么?

来自分类Dev

ESP.restart() 在 NodeMCU 中究竟应该做什么?

来自分类Dev

具有自动默认值和移动构造函数的不可复制类

来自分类Dev

具有类内初始化的默认默认构造函数的行为是什么?

来自分类Dev

如果不在子类中创建子类对象,为什么父类必须具有默认构造函数?

来自分类Dev

ASCII字符26应该做什么?

来自分类Dev

--precompile标志应该做什么?

来自分类Dev

具有std :: string属性的默认移动构造函数行为

来自分类Dev

显式默认的构造函数做什么?

来自分类Dev

C ++ 03通过构造函数将向量移动到类成员中(移动语义)

来自分类Dev

默认情况下,taphold或click-hold应该做什么?

来自分类Dev

为什么即使我的抽象类具有受保护的构造函数,也要创建默认构造函数?

来自分类Dev

C ++类是否具有默认构造函数?在以下情况下会调用什么构造函数?

来自分类Dev

在仅具有需要参数的已定义构造函数的类中调用默认构造函数(在Java中)

来自分类Dev

具有默认构造函数的类中的重载()运算符

来自分类Dev

具有Java中构造函数默认值的超类覆盖子类

来自分类Dev

为什么带有用户声明的析构函数的类具有隐式默认构造函数?

来自分类Dev

在具有公共构造函数而不是受保护构造函数的抽象类中,有什么要点吗?

来自分类Dev

在webrtc回调“-(void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)peerConnection”中应该做什么?

来自分类Dev

交互式外壳在孤立的流程组中应该做什么?

来自分类Dev

交互式外壳在孤立的流程组中应该做什么?

来自分类Dev

Debian的/etc/init.d/umountfs中的sed命令应该做什么?

来自分类Dev

具有模板化构造函数以及复制和移动构造函数的类

Related 相关文章

  1. 1

    具有移动构造函数和分配的类的默认副本构造函数和分配

  2. 2

    在一个类中,“使用Base :: BaseOfBase;”应该做什么?

  3. 3

    另一个类的移动构造函数中的移动类(没有默认构造函数)

  4. 4

    netbeans中的Watch进程选项应该做什么?

  5. 5

    '{default:'1}在系统Verilog中应该做什么?

  6. 6

    Material-UI中的notched属性应该做什么

  7. 7

    Vis.js中的“ horizontalScroll”选项应该做什么?

  8. 8

    ESP.restart() 在 NodeMCU 中究竟应该做什么?

  9. 9

    具有自动默认值和移动构造函数的不可复制类

  10. 10

    具有类内初始化的默认默认构造函数的行为是什么?

  11. 11

    如果不在子类中创建子类对象,为什么父类必须具有默认构造函数?

  12. 12

    ASCII字符26应该做什么?

  13. 13

    --precompile标志应该做什么?

  14. 14

    具有std :: string属性的默认移动构造函数行为

  15. 15

    显式默认的构造函数做什么?

  16. 16

    C ++ 03通过构造函数将向量移动到类成员中(移动语义)

  17. 17

    默认情况下,taphold或click-hold应该做什么?

  18. 18

    为什么即使我的抽象类具有受保护的构造函数,也要创建默认构造函数?

  19. 19

    C ++类是否具有默认构造函数?在以下情况下会调用什么构造函数?

  20. 20

    在仅具有需要参数的已定义构造函数的类中调用默认构造函数(在Java中)

  21. 21

    具有默认构造函数的类中的重载()运算符

  22. 22

    具有Java中构造函数默认值的超类覆盖子类

  23. 23

    为什么带有用户声明的析构函数的类具有隐式默认构造函数?

  24. 24

    在具有公共构造函数而不是受保护构造函数的抽象类中,有什么要点吗?

  25. 25

    在webrtc回调“-(void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)peerConnection”中应该做什么?

  26. 26

    交互式外壳在孤立的流程组中应该做什么?

  27. 27

    交互式外壳在孤立的流程组中应该做什么?

  28. 28

    Debian的/etc/init.d/umountfs中的sed命令应该做什么?

  29. 29

    具有模板化构造函数以及复制和移动构造函数的类

热门标签

归档