未初始化的引用成员

21
基本上我想要做的是将精灵的活动动画引用作为Actor类中的私有成员变量进行存储。我想使用引用,这样就不必多次创建动画,但我一直收到错误信息。
Actor类声明:
class Actor
{
public:
        Actor();
        ~Actor();
        void setActiveAnimation(Animation anim);
        void draw(sf::RenderWindow& win);

private:
        sf::Sprite sprite;
        MaJR::Animation& activeAnimation;
};

Actor类的实现:

Actor::Actor()
{
    // constructor
}

Actor::~Actor()
{
    // destructor
}

void Actor::setActiveAnimation(Animation anim)
{
    activeAnimation = anim;
    activeAnimation.gotoStart();
}

void Actor::draw(sf::RenderWindow& win)
{
    sprite.setTexture(activeAnimation.getActiveFrame());
    win.draw(sprite);
    activeAnimation.nextFrame();
}

构建输出:

/home/mike/MaJR Game Engine/src/Actor.cpp||In constructor 'MaJR::Actor::Actor()':|
/home/mike/MaJR Game Engine/src/Actor.cpp|8|error: uninitialized reference member 'MaJR::Actor::activeAnimation' [-fpermissive]|
||=== Build finished: 1 errors, 0 warnings ===|

2
似乎在C++构造函数中初始化引用的第一个答案,就是你要找的答案。 - GM1
可能是在C++构造函数中初始化引用的重复问题。 - SimonC
4个回答

34

引用无法被“重新分配”,因此必须在“成员初始化列表”中进行初始化。但是,您打算重新分配它,因此您想要的不是引用。此外,在您的setActiveAnimation函数中,您正在将这种引用设置为传递的值的副本,这会使得当代码退出函数时,您将面临一个无效的引用。也许指针更适合您?

在类体中:

MaJR::Animation* activeAnimation;

setActiveAnimation 函数:

void Actor::setActiveAnimation(Animation* anim)
{
    activeAnimation = anim;
    activeAnimation->gotoStart();
}

6
你的分析很好,但我不能点赞一个使用引用传递参数地址的代码答案。如果你要存储指针以供稍后使用,请接受一个指针参数,以让调用者更加清楚生命周期的考虑。 - Ben Voigt
1
我同意原始指针不如智能指针好。但是引用更糟糕。对于这个修复操作点赞。 - Ben Voigt
所以发生了什么是 Actor::activeAnimation 是指向 anim 的指针,而 anim 又是指向原始 Animation 的指针?智能指针是什么,它们与原始指针有何不同? - user768417
@Mike:你可以像使用其他指针一样使用它,例如 activeAnimation->someFunction(); - K-ballo
让我们在聊天中继续这个讨论。 (Let us continue this discussion in chat.) - user768417
显示剩余6条评论

8

当你的类中有一个引用成员时,你必须在构造函数中进行初始化。一旦它被初始化,你就不能再改变它了(当然你可以改变它所指向的值,但不能改变它所指向的位置)。

将activeAnimation改为指针。


3
您不能声明一个未初始化的引用。这意味着您需要在创建类Actor的对象时初始化引用,否则您将无法使用引用。如果您需要动态更改它,则可以使用指针或者更好的是智能指针(例如std::unique_ptr, shared_ptr)。如果您无法使用C++11,则可以查看Boost库中的智能指针

2

定义时需要绑定引用。对于成员引用,这意味着在构造函数的初始化列表中进行绑定。此外,在声明后不能重新分配绑定。

如果你在 Actor 对象实例化时没有该对象(以获取引用),那么你下一个最好的选择是使用指针,它可以根据需要随后重新分配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接