C ++在循环中使用switch时的输出相同

时间:2014-04-08 00:33:46

标签: c++

我已经尝试使以下测试程序工作2天,但是它不起作用。它基于几个头文件完全正常工作,因为我通过另一个测试程序检查它们。它有头文件,称为Area,Circle,Ring,Rectangle和Square。我还定义了函数randcolor和randsize;我一遍又一遍地检查每一个,但是在while循环中第二次尝试后它会产生相同的ouptut:

int main()
{
  srand(time(NULL));
  Area *list[20];
  int m;
  Area *c;
  int j = 0;

  while (j < 20) {

    m = rand() % 4;
    cout << m << endl;

    switch (m) {
      case 0: {
        Circle a(randcolor(), randsize());
        c = &a;
        break; 
      }
      case 1: {
        Ring r(randcolor(), randsize(), randsize());
        c = &r;
        break;
      }
      case 2: {
        Rectangle re(randcolor(), randsize(), randsize());
        c = &re;
        break;
      }
      case 3: {
        Square sq(randcolor(), randsize());
        c = &sq;
        break;
      }
    }

    list[j] = c;
    j++;  
  }
  return 0;
}

请帮帮我 预期输出应如下: 2 区域构造函数被称为.. 1 区域构造函数被调用 0 区域构造函数称为

所以它应该是这样的: 20次随机数,介于0和3之间          “区域构造函数被称为......”

但它在第二次尝试后给出了相同的数字......在while循环中

2 个答案:

答案 0 :(得分:6)

不知道你想要多少深度,问题是你将临时对象的无效地址推入列表中。在输入每个案例时,将创建,处理,然后销毁生成的对象。地址可能会在下一个循环中重复使用,但只要剩下最后一个对象的范围就会无效。

试试这个:

int main()
{
    srand ( time(NULL) );

    Area *list[20];

    int j=0;
    while(j < sizeof(list)/sizeof(*list)))
    {
        switch ( rand() % 4 )
        {
            case 0:
            {
                list[j++] = new Circle(randcolor(),randsize());
                break;
            }

            case 1:
            {
                list[j++] = new Ring(randcolor(),randsize(),randsize());
                break;
            }

            case 2:
            {
                list[j++] = new Rectangle(randcolor(),randsize(),randsize());
                break;
            }

            case 3:
            {
                list[j++] = new Square(randcolor(),randsize());
                break;
            }
        }
    }

    // TODO: Use your Area array list


    // cleanup
    for (int i=0; i<j; ++i)
        delete list[i];

    return 0;
}

我建议花一些时间学习动态分配。一旦你这样做,甚至花费更多时间学习标准库容器和智能指针,这可以减轻你的大部分头痛。


替代(迟早你会想要学习这些东西)

#include <iostream>
#include <vector>
#include <memory>
#include <random>

// include your Area and other declarations here

int main()
{
    std::random_device rd;
    std::mt19937 rng(rd());
    std::uniform_int_distribution<> dist(0,3);


    std::vector< std::unique_ptr<Area> > list;

    for (int i=0; i<20; ++i)
    {
        switch ( dist(rng) )
        {
            case 0:
                list.emplace_back(new Circle(randcolor(),randsize()));
                break;

            case 1:
                list.emplace_back(new Ring(randcolor(),randsize(),randsize()));
                break;

            case 2:
                list.emplace_back(ew Rectangle(randcolor(),randsize(),randsize()));
                break;

            case 3:
                list.emplace_back(new Square(randcolor(),randsize()));
                break;
        }
    }

    // TODO: Use your Area array list
    for (auto& ptr : list)
    {
        ptr->Method();
    }

    return 0;
}

答案 1 :(得分:0)

您的代码的一个问题是您似乎在切换案例中构造临时对象,并且一旦范围结束,您的c变量将不再指向有效对象,因为结束案例范围。

修复方法是在switch语句之前移出构造,但仍然在while循环中,或者只使用指针(如果你愿意的话,甚至可以是智能的)。

我将举例说明一个开关盒的情况,其余部分可以遵循:

 case 0:
    {
        list[j++] = new Circle(randcolor(), randsize());
        break;
    }