编译器调用复制运算符而不是移动运算符



事先在这里找到了一个确切的问题,但我没有相同的问题原因(或者至少我认为是这样(。我的AnimatedSprite类有一个Timer成员,该成员不可复制(显式删除了复制 ctor 和 operator= (。然而,当我尝试在其他类的 ctor 中启动一个精灵时,我收到一个错误,说我引用了已删除的复制运算符 =。

计时器:

#pragma once
#include <set>
class Timer
{
public:
Timer() :
currentTime_{0},
expirationTime_{0}
{}
Timer(unsigned expirationTime) :
currentTime_{ expirationTime },
expirationTime_{ expirationTime }
{
timers_.insert(this);
}
~Timer() {
timers_.erase(this);
}
// Here
Timer(const Timer& other) = delete;
Timer& operator=(const Timer& other) = delete;
Timer(Timer&& other) = default;
Timer& operator=(Timer&& other) = default;

//   Assumes the user knows if |this| is active or not
unsigned currentTime() const { return currentTime_; }
bool active() const { return currentTime_ < expirationTime_; }
bool expired() const { return !active(); }
void reset() { currentTime_ = 0; }
void disable() { currentTime_ = expirationTime_; }

static void updateAll(unsigned elapsedTime);
private:
void update(unsigned elapsedTime) {
if (active()) {
currentTime_ += elapsedTime;
}
}

static std::set<Timer*> timers_;
unsigned currentTime_;
const unsigned expirationTime_;
};

动画精灵.h

#pragma once
#include <vector>
#include <map>
#include "Globals.h"
#include "Sprite.h"
#include "Timer.h"

class Sprite;
class Graphics;
class AnimatedSprite : public Sprite
{
public:
AnimatedSprite() = default;
AnimatedSprite(Graphics& graphics, const std::string& filePath,
int sourceX, int sourceY, int width, int height,
unsigned frameLength, unsigned frameCount);
void update(bool once = false);
const bool completedOnce() const { return once_; }
private:
Timer frameTimer_;
unsigned currentFrame_{ 0 };
unsigned totalFrames_;
bool once_{ false };    //  if true, plays animation once
};

然后我这样做:

sprite_ = AnimatedSprite( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

不应该在这里调用移动运算符吗?我的 RHS 不是在右值上方的行中吗?

你的AnimatedSprite的某些东西会阻止它移动。 一旦消除,它就会尝试复制。 你得到了你的错误。

Sprite中可能存在某些东西阻止它被移动。 或者Timer的东西; 如果你不能移动东西,=default会变得=delete

我使用的一种技术是注入有关此类假设的静态断言。

static_assert( std::is_move_assignable<Sprite>{}, "Cannot move Sprite" );
static_assert( std::is_move_constructible<Sprite>{}, "Cannot move Sprite" );
static_assert( std::is_move_assignable<Timer>{}, "Cannot move Timer" );
static_assert( std::is_move_constructible<Timer>{}, "Cannot move Timer" );

现在,使用我的大脑编译器,我可以看到:

const unsigned expirationTime_;

将阻止Timer上的移动分配。

备份到设计:

sprite_ = AnimatedSprite( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

一个当前正在制作动画的精灵分配给另一个精灵是否有意义?

我怀疑。

我会=deleteoperator=(&&).

sprite_替换为std::optional<AnimatedSprite>,然后执行以下操作:

sprite_.emplace( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );

这通常比拥有"处于非精灵状态的精灵"要理智得多。

最新更新