gpt4 book ai didi

c++ - 如何定义移动构造函数?

转载 作者:IT老高 更新时间:2023-10-28 21:55:04 25 4
gpt4 key购买 nike

我正在 Visual Studio 11 上尝试一些新的 C++11 功能,从移动构造函数开始。我编写了一个名为“MyClass”的简单类,其中包含一个移动构造函数:

class MyClass
{
public:
explicit MyClass( int aiCount )
: mpiSize( new int( aiCount ) ),
miSize2( aiCount)
{
}

MyClass( MyClass&& rcOther )
: mpiSize( rcOther.mpiSize )
, miSize2( *rcOther.mpiSize )
{
rcOther.mpiSize = 0;
rcOther.miSize2 = 0;
}

~MyClass()
{
delete mpiSize;
}

private:
int *mpiSize;
int miSize2;

};

这里有问题:

  1. 我假设编译器会为 MyClass 生成一个移动构造函数,如果我不实现一个 - 但它似乎不是这样?
  2. 移动构造函数的实现对于 MyClass 是否正确?
  3. 有没有更好的方法来实现 MyClass 的移动构造函数?

最佳答案

  1. MSVC++ 在标准的最终版本发布之前实现了移动构造函数。在标准 MSVC++ 的实现所基于的版本中,生成默认移动构造函数的规则比标准的最终版本严格得多。见这里:Why is this code trying to call the copy constructor? (特别是 this answer 及其评论)以获取更多信息。这在 Visual Studio 11 中没有也不会修复, 出于某种未知的愚蠢原因 ,因为它们有其他优先级。

  2. 不,你需要在 rcOther 的成员上调用 std::move,然后你用死对象的相应成员初始化成员(你miSize):

    MyClass( MyClass&& rcOther )
    : mpiSize( std::move(rcOther.mpiSize) )
    , miSize2( std::move(rcOther.miSize2) )
    {
    rcOther.mpiSize = 0;
    }

    它对像 intint* 这样的内置类型没有影响,但它肯定对用户有影响-定义类型。

    • 这样做的原因是 std::move 只是返回转换为 T&& 的参数,一个右值引用,因此正确的构造函数 (为每个子对象调用移动构造函数 T(T&&))。如果你不对濒死对象的成员使用 std::move,它们将被视为 T&,并且你的子对象的复制构造函数( T(T&)) 将被调用而不是移动构造函数。这非常糟糕,几乎阻碍了您编写移动构造函数的全部目的。


3. 你在做一些不必要的事情,比如将整数设置为 0。你只需要将指针设置为 0,这样 delete 就不会删除你创建的新对象的资源。

另外,如果这不是一个教学练习,您可能需要考虑使用 std::unique_ptr 而不是管理自己对象的生命周期。这样,您甚至不必为您的类(class)编写析构函数。请注意,如果您这样做,则必须使用 std::move 从移动构造函数中的垂死成员初始化该成员。


  • Konrad Rudolph 在他的回答中发现了这样一个事实,即您的类(class)管理非自动资源但不遵循 三、四或五的规则。有关更多详细信息,请参阅他的回答。

关于c++ - 如何定义移动构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9456910/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com