-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 回答