如何知道对象是否被移动

时间:2018-02-21 14:05:09

标签: c++ design-patterns

这可能是一个愚蠢的问题,但我觉得我错过了一些设计模式。

在课程被破坏期间,如果移动或不移动,我想做不同的操作。我想过要实现一个在移动类时勾选的简单布尔值。

像这样:

class A {
    A(A && a) {
        a.was_moved = true;
    }

~A() {
    do some stuff

    if (!was_moved) {
        clean some more stuff
    }

bool was_moved = false;
};

是否有更好的"这样做的方式?一些cpp功能我可以询问是否移动了类或一些已知的设计模式。

2 个答案:

答案 0 :(得分:2)

没有允许这样做的功能。但通常你不需要知道。

通常,当您定义移动构造函数时,您希望它将基础数据从一个对象“移动”到另一个对象。在您的上下文中,您似乎希望源对象之后为“空”,以便只有一个所有者(毕竟它是“移动”,而不是“复制”)。所以你真正需要的是对“空”对象的正确定义以及处理这种情况的正确方法。

例如,假设您的类与文件描述符相关联。然后你可以有一个默认值fd等于-1并区分析构函数:

#include <utility>

class A
{
    public:
        A(int fd) : fd { fd }
        {
        }

        A(A&& other) : fd { std::exchange(other.fd, -1) }
        {
        }

        ~A()
        {
            if (fd != -1)
            {
                close(fd);
            }
        }

    private:
        int fd = -1;
};

当然,您可以通过附加标记将对象标记为空。事实上,人们会在某些特殊情况下这样做。即使在标准库中。您可能需要read this。请注意__owns_类上的unique_lock标记。

答案 1 :(得分:2)

没有标准的方法来了解它。但这很重要 定义移动构造函数和移动分配,以便您可以清理 在移动之前执行exisitng对象的资源:

class MoveDemo
{
    size_t size;
    char *buf;

    public:
    explicit MoveDemo(int sz=1024):size(sz), buf(new char[size]) {}
    ~MoveDemo { delete [] buf; }
    MoveDemo(MoveDemo&& other);
    MoveDemo& operator=(MoveDemo&& other);
};

MoveDemo::MoveDemo(MoveDemo&& other):size(0), buf(nullptr)
{
    size = other.size;
    buf = other.buf;

    //reset other
    other.size = 0;
    other.buf = nullptr;
}

MoveDemo& MoveDemo::operator=(MoveDemo&& other)
{
    if (this != &other)
    {
        // release current objects resources
        delete [] buf;
        size = 0;

        // move
        size = other.size;
        buf = other.buf;

        //reset other
        other.size = 0;
        other.buf = nullptr;
    }
    return *this;
}