web-dev-qa-db-ja.com

メンバーunique_ptrを空に初期化します

私のプログラムには、カスタムクラス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にアクターがあるわけではないため、ほとんどの場合、Positionオブジェクトのunique_ptr「actor」は空である必要があります(unique_ptrsを使用して、実行時にPositionに関連付けられたアクターを自動的にクリーンアップします)。

位置コンストラクターは次のとおりです。

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

ただし、Position :: getActor()内でactor.get()を呼び出そうとすると、次のようなエラーが発生するため、保存されているポインターがnullptrに正しく設定されていないことがわかります。

____。exeの0x01096486での初回例外:0xC0000005:アクセス違反の読み取り場所0x00000008。

メンバーunique_ptrをnullptrに初期化する方法はありますか?アクターがアクティブかどうかを定義する変数をActorクラスに追加し、unique_ptrを新しい非アクティブなアクターに設定し、すべての非アクティブなアクターを無視することでこれを回避できることはわかっていますが、可能であればこれを避けたいと思います。

ありがとう!

編集: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;
    }
}
11
PreacherJayne

あなたのエラーはここにあります:

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

std::moveの結果をパラメータactorに割り当てています。おそらく reset メンバー変数actorとパラメーター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に初期化されます。

7
emlai

Std :: uniqueポインタをnullに初期化する必要はありません。コンストラクターでデフォルトの空の値のままにし、null以外のポインターを指すようにリセットするだけです。