ページ 11

STLコンテナStackの動作について

Posted: 2019年9月29日(日) 20:36
by さいぎょー
龍神録2プログラミングの館にてC++オブジェクト指向によるゲーム製作を勉強しています。

同サイトの第5章( https://dixq.net/rp2/05.html )にて以下のようなシーンを変更するメゾットがあるのですが、引数のstackClearがtrueのときはSOMESceneインスタンスが1回全てクリアされます。

コード:

// Looper.cpp
void Looper::onSceneChanged(const eScene scene, const Parameter& parameter, const bool stackClear)
{
    if (stackClear) {//スタッククリアなら
        while (!_sceneStack.empty()) {//スタックを全部ポップする(スタックを空にする)
            _sceneStack.pop();
        }
    }
    switch (scene) {
    case Title:
        _sceneStack.push(make_shared<TitleScene>(this, parameter));
        break;
    case Game:
        _sceneStack.push(make_shared<GameScene>(this, parameter));
        break;
    default:
        //どうしようもないエラー発生
        break;
    }
}
このメゾットをSOMESceneから呼び出しているのですが、以下のようなメゾットだと自分自身のクラスのインスタンスがクリアされてからreturn;を行っているように見えます。ですが正しく実行されています。

コード:

void TitleScene::update()
{
    if (CheckHitKey(KEY_INPUT_E)) {
        Parameter parameter;
        parameter.set(GameScene::ParameterTagLevel, Define::eLevel::Easy);
        const bool stackClear = false;
        _implSceneChanged->onSceneChanged(eScene::Game, parameter, stackClear);
        return;
    }
    if (CheckHitKey(KEY_INPUT_N)) {
        Parameter parameter;
        parameter.set(GameScene::ParameterTagLevel, Define::eLevel::Normal);
        const bool stackClear = false;
        _implSceneChanged->onSceneChanged(eScene::Game, parameter, stackClear);
        return;
    }
}
return文が存在しない場合はアクセス違反(?)が起きて強制終了しました。

このようにインスタンスがクリアされた後にそのインスタンスのreturn文を実行する場合は問題がないのでしょうか?

また、シーンを一つ戻すような動作をさせるメゾットをonSceneChangedと同じように作ることを考えています。
この場合Looperクラスにて_sceneStack.pop()を一度行えばいいと思うのですがいかがでしょうか?

Re: STLコンテナStackの動作について

Posted: 2019年10月02日(水) 18:04
by dic
気持ち悪い

Re: STLコンテナStackの動作について

Posted: 2019年10月02日(水) 18:31
by usao
何を問題にしているのか読み取りにくい…

(1)スタックの要素はshared_ptrであるから,popしたからといって,shared_ptrが要素を削除するかどうかはわからない.
(リンク先は続き物みたいなので過去記事までさかのぼって確認すればその辺がどうなってるのかがわかるのかもだけど,そこまで労力割きたくないので…)

(2)仮にpopする瞬間に要素が削除されるのだとして,returnするだけとかなら問題ない.
インスタンスが削除されたからといって,コードがなくなるわけじゃないので,
インスタンスに依存しない処理であれば問題ない.
ざっくり言えば,そのインスタンスのメンバ変数の読み書きをしないなら大丈夫.
「C++ delete this」とかでググれば,そこらへんの話が見つかるかも.

Re: STLコンテナStackの動作について

Posted: 2019年10月02日(水) 18:45
by usao
オフトピック
それはそれとして,

「ルール:なんたらSceneだのいうクラスを実装する際には『自分のメソッド実行中に自身がdeleteされ得ることに十分注意すること』」

とか何とか言われたらとても嫌だと思うので,
スタックなりを管理している側(?)でその辺はそうならんようにしておけば良いのではないかな.