GameState 的 C++ 移动语义

问题描述 投票:0回答:1

我的任务是在 C++ 中为机器人游戏实现移动语义(移动构造函数和移动赋值运算符)。

我收到一些反馈,说在使用移动语义时我应该从另一个对象“窃取”资源,所以我尝试这样做,但后来有人说这是一个浅拷贝,并且 std::move 不是必需的。还有人问当 GameState 超出范围时会发生什么并且可能无法正确处理。

当我从一个级别转到下一个级别时,mainwindow.cpp 中有一行使用赋值运算符。从未使用过移动构造函数,只需正确实现即可。

主窗口.cpp:

gameState = GameState(numberOfRobots); // constructor called

游戏状态.cpp:

// Constructor.
GameState::GameState(int numberOfRobots) {
    for (int i = 0; i < numberOfRobots; i++) {
        Robot* robot = new Robot();
        units.push_back(robot);
    }
    teleportHero();
}

// Move constructor. Is never called. 
GameState::GameState(GameState&& other) noexcept {
    units = move(other.units);
}

// Move assignment operator. Is called when going from one level to the next level (gameState = ...)
GameState& GameState::operator=(GameState&& other) noexcept {
    if (this != &other) {
        for (Unit* unit : units)
            delete unit;

        // steal all units from other to this GameState using move()
        units = move(other.units);
    }

    // returns a reference to the object into which the data was moved
    return *this;
}

我需要有关如何编写移动构造函数和移动赋值运算符的帮助。如果需要更多代码,请告诉我。

c++ move-semantics move-constructor move-assignment-operator
1个回答
0
投票

根据四分半规则,你的移动构造函数和移动赋值运算符应该只

swap
一个对象的内容与另一个对象的内容,这提供了强大的异常安全保证,并防止像 self 这样的意外错误移动作业。

#include <vector>
struct foo; // forward declaration
void swap(foo& a, foo& b) noexcept;

struct foo
{
    std::vector<int> vec;
    int* data;
    foo(): vec(), data(nullptr) {}
    foo(foo&& other): foo() // call default constructor
    {
        swap(*this, other);
    }
    foo& operator=(foo&& other)
    {
        swap(*this, other);
        return *this;
    }
};
void swap(foo& a, foo& b) noexcept
{
    std::swap(a.vec,b.vec);
    std::swap(a.data,b.data);
}

这需要一个默认构造函数,将对象置于已定义的状态(所有指针应为空,所有向量应为空)。

© www.soinside.com 2019 - 2024. All rights reserved.