try / catch的奇怪行为

时间:2012-12-12 16:59:49

标签: c++ try-catch stdmap

我的问题是:为什么以下代码:

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个容器中的不同数据类型的多个地图,这就是我想出来的

2 个答案:

答案 0 :(得分: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;
};

答案 1 :(得分: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;
}
相关问题