我确实事先在这里找到了一个确切的问题,但是我没有相同的原因(或者至少我是这样认为的)。我的AnimatedSprite
类具有Timer
成员,该成员被制成不可复制的(明确删除了copy ctor和operator =)。但是,当我尝试在其他类的ctor中初始化sprite时,却收到一条错误消息,指出我正在引用已删除的copy operator =。
Timer.h:
#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_;
};
AnimatedSprite.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 );
难道不应该在这里叫移动运算符(operator)吗?我的RHS是否不在右值上方的行中?
最佳答案
有关您的AnimatedSprite
的某些信息,它无法移动。一旦消除,它将尝试复制。而您得到您的错误。Sprite
中的某些内容可能阻止它被移动。或Timer
中的内容;如果您无法移动东西,=default
可以变成=delete
。
我使用的一种技术是注入(inject)有关此类假设的静态断言。
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 );
这通常比拥有“处于非精灵状态的精灵”更为理智。