2011-12-03 22 views
1

我創建了一個簡單的程序,在命令提示符下「繪製」形狀。我正在使用幾個類實現,但主要問題在Command抽象類中,更具體地說是該類中的析構函數。我用我定義的DEBUG模式編譯它,每次析構函數刪除一個對象時,都會打印一個'-'在循環的第一遍時刪除保留字不調用析構函數

Command類看起來是這樣的:

class Command { 
    public: 
     Command(){ 
#ifdef DEBUG 
      std::cout << '+'; 
#endif 
     } 
     virtual ~Command() { 
#ifdef DEBUG 
      std::cout << '-'; 
#endif 
     } 
     virtual void execute() = 0; 
     virtual void unexecute() = 0; 
}; 

我在另一個類中調用循環如下:

vector<Command*> history_; 

while(position_ != 0) { 
    delete *history_.end(); 
    history_.pop_back(); 
    position_--; 
} 

如果position_大於1將打印'-' N - 1次,但它不會在第一次刪除循環時調用析構函數。

+4

'矢量 ::端()'不迭代器返回一個有效的對象。 –

+0

難道你沒有看到它,因爲輸出緩衝?如果用'std :: cout.flush()'刷新緩衝區,會怎麼樣? –

回答

1

對於STL容器end()不引用最後一個項目,但就在最後一個項目之後的地方

0

這是因爲0不會被刪除,因爲position_ != 0不包括0,所以你將在向量中留下一個命令。
將其更改爲

while(position_ >= 0) 

,然後0將被一併刪除。

0

你有幾個問題:

  • end()一個過去的矢量結束,它並不適合你delete一個有效的元素(你已經錯了end()back())。由於您正在使用count變量來遍歷循環,因此您還可以使用隨機訪問(即history_end[i])訪問vector中的元素。

  • 您的情況應該是position_ >= 0,以便第0個元素可以是delete d。

3

那麼,一個向量的最後一個元素不是*history_.end()它是history_.back()

現在,如果position確實表示一個位置,您應該讓它達到0.但是,如果它是一個項目數的計數,您應該將其重命名爲countsize

由於矢量已經包含了方法來測試時,它是空的,你甚至可以拋棄你的自定義計數器,而不用擔心是否應該達到0或不:

while(!history.empty()) { 
    delete history_.back(); 
    history_.pop_back(); 
} 

但因爲你實際結算在整個向量中,不需要一次只彈出一個元素。您可以遍歷矢量,將它們刪除,然後一次向量clear()

for(size_t i = 0; i < history_.size(); ++i) { 
    delete history[i]; 
} 
history_.clear(); 

或者在C++ 11:

for(auto ptr : history_) { 
    delete ptr; 
} 
history_.clear(); 
相關問題