2014-04-08 29 views
1

我試圖讓以下測試程序工作2天,但它不工作。它基於幾個工作完好的頭文件,因爲我通過另一個測試程序檢查了它們。它具有名爲Area,Circle,Ring,Rectangle和Square的頭文件。我還定義了函數randcolor和randsize;我檢查everyhting一遍又一遍,但它是生產相同ouptut aftera while循環第二次嘗試:C++同時使用開關內部同時輸出while循環

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; 
} 

請幫我 預期的輸出應該是這樣的:區構造函數被調用.. 區構造函數被調用區構造函數被調用

所以它應該是這樣的: 20次randomnumber 3介於0和 「區域構造函數被調用......」

但它給了第二次嘗試...在後相同數量的同時,與您的代碼迴路

+1

請提供期望的輸出,電流輸出。 – merlin2011

+4

你知道塊範圍是什麼,它對你正在處理的底層對象有什麼影響?例如,「情況0」。一旦中斷命中,範圍被留下並且'a'被銷燬,留下'c'作爲不確定的指針。把它添加到你的陣列就是爲了這個UB蛋糕。 – WhozCraig

+1

這解釋了很多... –

回答

0

一個問題是,你似乎構建開關的情況下臨時對象,一旦範圍已經結束了,你的c由於案例範圍末尾的自動銷燬,變量不會再指向有效的對象。

解決的辦法是在switch語句之前移出構造,但仍然在while循環中,或者只是使用指針(如果你願意的話可能會更聰明)。

我會給你一個開關的情況下,其可以遵循所有其他的例子:

case 0: 
    { 
     list[j++] = new Circle(randcolor(), randsize()); 
     break; 
    } 
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; 
} 
+0

非常感謝WhozCraig,但是現在該程序正在構建一個具有相同對象的向量,所有對象都是同樣意味着其中一個switch語句被稱爲20次.. –

+0

Sry。正在修剪草坪。除非randXXXXX函數存在重大問題,否則我很難想象。刪除一些std :: cerr <<「在這裏!」在施工開關的情況下,確保它們均勻分佈。顯然,沒有更多的源代碼(就像所有幾何圖形的源代碼),我只能做很多事情。我在想象如果你使用後面的代碼,'srand()'應該放在main的最頂端,因爲'randXXXXX()'函數可能需要播種。 – WhozCraig