将类成员unique_ptr初始化为空

17

在我的程序中,我有一堆自定义类Position的对象。Position的声明如下:

class Position {
public:
    Position(int x, int y);
    ~Position();

    Actor *getActor()           { return actor.get(); };
    void setActor(Actor *actor) { actor = std::move(actor); };
    Actor *clearActor()         { return actor.release(); };

    int getX()  { return x; };
    int getY()  { return y; };

private:
    int x, y;
    std::unique_ptr<Actor> actor;
};

我也有一个名为Actor的类。并非每个Position都会有一个Actor,因此大多数情况下,与Position对象关联的unique_ptr“actor”应为空(我使用unique_ptr来自动清理与Position相关联的任何Actor)。

Position构造函数如下:

Position::Position(int x, int y)
{
    this->x = x;
    this->y = y;
    actor.reset(nullptr);
}

然而,我知道这并没有正确地将存储的指针设置为nullptr,因为当我尝试在Position::getActor()内部调用actor.get()时,我会收到以下错误:

在____.exe中的0x01096486处第一次机会异常:访问地址0x00000008时发生0xC0000005异常。

有没有一种方法可以将成员unique_ptr初始化为nullptr? 我知道我可以通过向Actor类添加一个变量来解决这个问题,该变量定义Actor是否活动,将unique_ptr设置为一个新的不活动的Actor,并忽略所有不活动的Actor,但如果可能的话,我宁愿避免这样做。

谢谢!

编辑:我已添加了调用getActor的代码:

bool Grid::addActor(Actor *actor, int x, int y)
{
    Position *destination = at(x, y);

    if (!destination->getActor()) {
        destination->setActor(actor);
        actor->setPosition(x, y);
        actor->setGrid(this);
        return true;
    }
    else {
        inactive_actors.emplace_back(actor);
        return false;
    }
}

2
你正在取消引用 getActor() 吗? - user3920237
你是指使用一个位置指针来调用它吗?是的。我有一个Position *pos,并且我正在检查pos->getActor()的值。 - PreacherJayne
@PreacherJayne 如果 getActor() 返回 nullptr,那就是未定义行为。 - user3920237
@PreacherJayne 你是否在解引用 getActor 返回的 nullptr - emlai
显示剩余3条评论
2个回答

11

你的错误在这里:

void setActor(Actor *actor) { actor = std::move(actor); };

您正在将std::move的结果分配给actor 参数。您可能想要使用参数actor reset成员变量actor

void setActor(Actor *actor) { this->actor.reset(actor); };

顺带一提,你可以简单地将你的构造函数更改为:

Position::Position(int x, int y)
: x(x), y(y)
{
}

这将使用参数初始化成员xy,并将std::unique_ptr<Actor> actor默认初始化为null。


太好了!我正要提到它。 - emlai
@PreacherJayne 构造函数初始化列表是构造函数定义的一部分,就像函数体一样,因此不需要将它们放在构造函数声明中。 - emlai
没错,这正是我想做的(而且,如果你不能使用它,为什么要允许返回 nullptr 呢???)。那么我需要另一种存储演员的方式了。感谢您的帮助! - PreacherJayne
1
@PreacherJayne 当然你可以使用它。只是不允许对其进行解引用操作。例如,if (!destination->getActor()),在这里,当getActor返回nullptr时,你使用nullptr来检查目标位置是否存在一个角色。 - emlai
那算不算取消引用它,还是只是正常使用?如果这是一个愚蠢的问题,请原谅。我的编程背景主要是Java和C。 - PreacherJayne
显示剩余9条评论

10

您无需将std::unique指针初始化为null。只需在构造函数中将其保留为默认的空值,并仅将其重置为指向非空指针。


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