我事先在这里找到了一个确切的问题,但我没有相同的问题原因(或者至少我认为是这样(。我的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 );
将一个当前正在制作动画的精灵分配给另一个精灵是否有意义?
我怀疑。
我会=delete
operator=(&&)
.
将sprite_
替换为std::optional<AnimatedSprite>
,然后执行以下操作:
sprite_.emplace( graphics, "Resource/NpcSym.png", 0, 1, 16, 16, 50, 5 );
这通常比拥有"处于非精灵状态的精灵"要理智得多。