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

从右值删除移动构造函数并构造对象

宗意蕴
2023-03-14

我试图理解“有效现代C”中关于特殊成员函数生成的第17项,所以我尝试了一些示例,并试图对一些行为进行推理。书中说:

..当我提到移动操作move构造或移动分配一个数据成员或基类时,不能保证实际会发生移动。“Memberwise移动”实际上更像Memberwise移动请求,因为未启用移动的类型(即,对移动操作不提供特殊支持的类型,例如大多数C 98遗留类)将通过其复制操作“移动”。。。此外,不会为任何显式声明复制操作的类生成移动操作。

如果我显式删除move构造函数,下面的代码会出错,但如果我不删除,则对象“s1”会在没有任何错误的情况下得到copy构造。这里有一个指向同一代码的魔杖盒链接:魔杖盒链接。我想我不明白删除移动构造函数和不定义构造函数之间的区别。

#include <iostream>

struct S
{
    S() = default;
    S(const S&) {
        std::cout << "Copying" << std::endl;
    }
   // S(S&&) = delete;
};

S return_lvalue() {
    S ret{};
    return ret;
}

int main() {
    std::cout << "Hello world" << std::endl;
    // Error here if I delete move constructor
    S s1 = return_lvalue();
}

共有2个答案

诸葛阳成
2023-03-14

删除特殊成员函数与不声明它不同。这与声明它,然后在使用它时强制编译错误是一样的。

因此,删除移动向量没有太大的好处……除非您出于某种原因也删除了复制向量,但是根本不声明移动向量。

这与引用没有太大关系,引用是说如果你确实声明了一个移动ctor,但没有在其中做任何“移动的事情”,那么最终没有任何有价值的东西真正被移动,这可能与你的用户的期望相反。

我建议你不要宣布你的行动。同样,这与被删除的内容不同。一个将不会自动生成,因为您有一个副本。

请在此处查找更多技术信息:

  • “为什么删除的复制构造函数不允许使用其他多态类型的构造函数?”

请注意,由于省略,您的程序在这两种情况下都以C17模式编译。

微生恩
2023-03-14

我想我不明白删除移动构造函数和不定义构造函数之间的区别。

当你这么做的时候

struct S
{
    S() = default;
    S(const S&) {
        std::cout << "Copying" << std::endl;
    }
};

编译器不会生成移动构造函数。如果您尝试移动它,重载解析将只找到S(const S

struct S
{
    S() = default;
    S(const S&) {
        std::cout << "Copying" << std::endl;
    }
    S(S&&) = delete;
};

移动类型为S对象时,重载解析将查找S(常量S

您需要记住的是,删除的构造函数不会从类中删除它们。它声明它们并使它们可用于重载解析,只有在重载解析发生后,它才会检查是否已删除。

 类似资料:
  • 正如michaelpark所指出的,如果我们不想最终使用错误的构造函数,那么添加完美的转发构造函数可能会很棘手。 目前,我有一个类,它使用了一个完美的转发构造函数,因此,我需要显式声明4个构造函数:

  • 引用自C Primer 如果我们显式地要求编译器使用生成移动操作,并且编译器无法移动所有成员,那么移动操作将被定义为删除 如果类有一个定义自己的复制构造函数的成员,但不定义移动构造函数,或者如果类有一个不定义自己的复制操作的成员,并且编译器无法合成,则移动构造函数被定义为删除移动构造函数 有些代码似乎违反了这条规则: X没有定义移动构造函数,编译器不能为它合成一个。 根据上述规则,的移动构造函数被

  • JavaScript 中的构造函数和其它语言中的构造函数是不同的。 通过 new 关键字方式调用的函数都被认为是构造函数。 在构造函数内部 - 也就是被调用的函数内 - this 指向新创建的对象 Object。 这个新创建的对象的 prototype 被指向到构造函数的 prototype。 如果被调用的函数没有显式的 return 表达式,则隐式的会返回 this 对象 - 也就是新创建的对象

  • 我有以下课程布局: 我正在为服务创建一个单元测试,但我想将ServiceHelper用作一个“活动”类,但要模拟ServiceHelper中的构造函数参数。有没有办法通过Mockito实现这一点?

  • 问题内容: 我注意到,使用快捷方式并选择构建器,它尝试使用每个私有属性(例如和)创建一个构造器。我记得我已经创建了没有它的项目并且可以正常工作。 在完整的logcat和构造函数之后,运行应用程序时发生错误: 具有私有财产的建设者: Logcat: 问题答案: 您的所有初始化都应使用的方法执行: 覆盖的构造函数会涉及很多繁重的工作,实际上并不是在公园散步。尽管您当然 可以 为设置一个空的构造函数,但

  • 我正在读《C入门》第五版,遇到了以下问题。本书列出了将合成移动操作定义为已删除的几种情况。其中之一就是与复制构造函数不同,如果类有一个成员定义了自己的复制构造函数,但没有定义移动构造函数,或者类有一个成员没有定义自己的复制操作,并且编译器无法为其合成移动构造函数,则移动构造函数被定义为已删除。同样,移动分配也是如此。“并提供如下演示代码: 然而,对于gcc 7.2.1和clang-900.0.37