-3

私の質問はこれです: なぜ次のコードは:

class A
{
public:
    A()
    {
        test[0] = "three";
        test[5] = "five";
        test2[3] = 5.55;
    }
    void foo(int j)
    {
        for(int i = j+1; i <= 7; ++i)
        {
            try
            {
                std::cout<<test.at(i)<<"\n";
            }
            catch(const std::out_of_range&)
            {
                try
                {
                    std::cout<<test2.at(i)<<"\n";
                }
                catch(const std::out_of_range&)
                {
                    throw i;
                }
            }
        }
    }
    virtual void bar()
    {

    }
    std::map< int, float > test2;
    std::map<int, std::string> test;
};

class B : public A
{
public:
    B()
    {
        test3[6] = 15;
        test3[7] = 42;
        bar();
    }

    void bar()
    {
        int k = -1;
        label:
        try
        {
            foo(k);
        }
        catch(int i)
        {
            try
            {
                std::cout<<test3.at(i)<<"\n";
            }
            catch(const std::out_of_range&)
            {
                k = i;
                goto label;
            }
        }
    }

std::map<int, int> test3;
};

印刷する

three
5.55
five
15

そしてそうではない

three
5.55
five
15
42

?

私がやろうとしているのは、1つのコンテナーに保持できないさまざまなデータ型を含む多数のマップを反復処理することです。これが私が思いついたものです

4

2 に答える 2

2

私の理解では、必要なものは次のとおりです。

  • 特定の範囲のキーで異なるマップに含まれるすべての値を出力したいとします。
  • マップにはさまざまなタイプの値があります。すべてのキーがすべてのマップに存在するわけではありません。
  • 派生クラスには、追加のマップが含まれる場合があります。

この複雑な例外 + goto デザインの代わりに、特定の値を出力するための仮想メソッドに基づいたより単純なデザインを使用してみませんか?

class A {
public:
    virtual void showValue(int key) {
        if (map1.count(key))
            std::cout << map1[key];
        else if (map2.count(key))
            std::cout << map2[key];
    }

    void showAll() {
        for (int i=0; i<=7; i++)
            showValue(i);
    }

    std::map<int, float> map1;
    std::map<int, std::string> map2;
};

class B : public A {
public:
    virtual void showValue(int key) {
        if (map3.count(key))
            std::cout << map3[key];
        else
            A::showValue(key);
    }

    std::map<int, int> map3;
};
于 2012-12-12T17:23:55.713 に答える
1

何が起こっているかというと、15 を出力するとthrow i. これはキャッチされず、次のようにエスケープされます。

   catch(int i)
    {
        try
        {
            std::cout<<test3.at(i)<<"\n";
        }
        catch(const std::out_of_range&)
        {
            k = i;
            goto label;
        }
    }

番号はそこに正しく印刷されますが、再起動しません。詳細を知らなければ、それを修正する方法を理解することは事実上不可能です...

はるかに優れたソリューションは次のようになります。

for (int i=0;i<=7;i++)
{
    if (test.find(i)!=std::map::end)
      std::cout<<test.at(i)<<"\n";
    else if (test2.find(i)!=std::map::end)
      std::cout<<test2.at(i)<<"\n";
    else if (test3.find(i)!=std::map::end)
      std::cout<<test3.at(i)<<"\n";
    else
      std::count<<"Nothing Found"<<std::endl;
}
于 2012-12-12T17:05:17.383 に答える