インスタンス化に失敗した際の処理について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
array

インスタンス化に失敗した際の処理について

#1

投稿記事 by array » 15年前

お世話になっております。今回はC++のクラスの動作について質問させて下さい。

(例)
class CTest
{
CTest() { throw "Error"; }
void print() { std::cout << "Hello" << std::endl; }
};

int main()
{
CTest* test;
try
{
test = new CTest();
}
catch (...)
{
test = NULL;
}

test->print(); // ポイント①

return 0;
}


上記の例の様な(例)でクラスの生成に失敗したら例外を投げるクラスを作成したのですが
失敗(例外を検出)した際に、ポインタにNULLを入れていました。

個人的には、ポイント①の箇所では、test = NULLの時は処理を行わず飛ばしてくれると
有難いのですが、NULLポインタの為、print()メソッドを参照できないみたいです。

纏めると、インスタンス化に失敗してもprint()メソッド部でエラーが起きないようにしたいのですが
可能でしょうか。

宜しくお願いします。

めるぽん

Re:インスタンス化に失敗した際の処理について

#2

投稿記事 by めるぽん » 15年前

if (test != NULL) test->print();
ではダメなんでしょうか?もしくは
print_if_not_null(CTest* p)
{
    if (p != NULL) p->print();
}

int main()
{
    ...
    print_if_not_null(test);
    ...
}
とか。あるいは Proxy パターンなんかも使えるかもしれません。
struct ITest
{
    virtual void print() = 0;
};
struct CTest : ITest
{
    virtual void print() { std::cout << "Hello" << std::endl; } 
};
struct NullTest : ITest
{
    virtual void print() { } // 何もしない
} nullTest;

int main()
{
    try {
        ...
    } catch (...) {
        test = &nullTest;
    }
    test->print();
}
詳細は Proxy パターンとか調べれば分かると思います。


最後に、トリッキーというか、仕様的に問題がありそうなコードで良ければ、
struct CTest
{
    void print()
    {
        if (this == NULL) return;
        std::cout << "Hello" << std::endl;
    }
};

int main()
{
    CTest* test = NULL;
    test->print();
}
と書くこともできますね。

array

Re:インスタンス化に失敗した際の処理について

#3

投稿記事 by array » 15年前

色々な案有難うございます♪

個人的にはProxy パターンが一番イメージに近いです。
クラスを1つ経由する事で、インスタンスが正常に
行われていないかのチェックが一纏めに出来るわけですね。

Proxyパターンを参考に再設計させてもらいます。有難うございました^^

--

> if (test != NULL) test->print();

これだと、test->print()の仕様箇所が多くなると
変更時の作業が大変になるのであまり好ましくないのかなと思っていました。

> print_if_not_null()

書き損じましたが、オブジェクト思考を念頭に組んでみたかったので
可能であれば関数は避けようかと思います。


めるぽんさんのコードを見て気づきましたが
「if (test != NULL) test->print();」このコードをマクロ化するのも良いかと思いました。 画像

閉鎖

“C言語何でも質問掲示板” へ戻る