2010-10-23 109 views
2
#include <boost/ptr_container/ptr_vector.hpp> 
#include <iostream> 
using namespace std; 

class Derived 
{ 
public: 
     int i; 
     Derived() {cout<<"Constructed Derived"<<endl;} 
     Derived(int ii):i(ii) {cout<<"Constructed Derived"<<i<<endl;} 
     ~Derived() {cout<<"* Destructed Derived"<<i<<endl;} 
}; 

int main() 
{ 
    boost::ptr_vector<Derived> pv; 
    for(int i=0;i<10;++i) pv.push_back(new Derived(i)); 

    boost::ptr_vector<Derived>::iterator it; 
    for (it=pv.begin(); it<pv.end();/*no iterator increment*/) 
     pv.erase(it); 
    cout<<"Done erasing..."<<endl; 
} 

請注意,第二個for循環不會遞增迭代器,但它會迭代和刪除所有元素。我的問題是:ptr_vector迭代器不需要增量嗎?

  1. 是我的迭代的技術,使用迭代是否正確?
  2. 如果for循環中不需要迭代器增量,那麼增量會在何處發生?
  3. 使用一個迭代器或將一個普通的整數是否更好(即:是否有使用迭代器的任何增值)? (因爲我也可以像pv.erase(pv.begin()+ 5)一樣擦除第五個元素;)
  4. 是否有任何方法將新對象分配給ptr_vector的特定位置(比方說第5個位置)直?我正在尋找像pv [5] = new Derived(5);的東西。任何方式做到這一點?

回答

1

我的迭代技術和使用迭代器是否正確?

不,從容器中擦除通常會使迭代器無效到已擦除項目。如果有效,這只是實施細節的副作用。

正確的方法是使用擦除方法的返回值:

it = pv.erase(it); 

然而,排空容器,可以用清晰的成員函數。

如果不需要迭代增量的for循環,然後在那裏 沒有增量發生?

它不會發生,因爲您總是會擦除容器中的第一個項目(偶然,可能無法與其他容器一起使用)。

是更好地使用迭代器或將一個普通的整數就足夠了(即: 有任何增值使用 迭代器)? (怎麼我還可以刪除像 pv.erase(pv.begin()+5);的 第五元素)

在一個隨機存取容器,你能做到這一點,否則沒有(如表)。

有什麼辦法到一個新的對象分配給ptr_vector的特定位置(讓我們 說,第5位), 直接?我在找東西 ,比如pv[5]=new Derived(5);。任何方式 這樣做?

依據升壓參考:

pv.replace(5, new Derived(5)); 

這個方法返回一個智能指針現有的指針,所以它會自動釋放。 (奇怪的是,這需要一個索引,而不是迭代器......)。

或者:

pv[5] = Derived(5); 

但這隻會修改存儲的對象,而不是改變指針。

3

一個ptr_vector::iterator增量就像一個正常的隨機訪問迭代器。在你的例子中,你可以擦除每個元素而不實際遞增,因爲在你擦除一個元素之後,元素之後的每個元素都被移到數組中。因此,當您擦除第0個元素時,您的迭代器現在指向使用作爲第1個元素的元素,但現在是第0個元素,依此類推。換句話說,當整個矢量向左移動時,迭代器保持原位。

這沒有什麼特別與ptr_vector。請注意,使用普通的std::vector會發生同樣的情況。

另請注意,在擦除指向它的元素之後使用迭代器是危險的。在你的情況下,它可以工作,但最好取ptr_vector::erase的返回值,這樣你可以得到一個保證有效的新迭代器。

for (it = pv.begin(); it != pv.end();) 
     it = pv.erase(it); 

至於你的其他問題:

如果你只是想刪除一個特定的元素,那麼你當然應該直接使用pv.erase(pv.begin() + N)擦除。要爲指針向量中的特定元素分配新值,只需說pv[N] = Derived(whatever)。重新分配值時,您不需要使用new。指針向量將調用指定新值的索引處的對象的賦值運算符。

+0

很酷!希望能回答問題3和4 :) – Nav 2010-10-23 09:59:19

+0

沒有。我試過PV [0] =派生(888);並獲得此輸出:構造Derived888 boostPtrVsSTL:/usr/include/boost/ptr_container/ptr_sequence_adapter.hpp:325:typename boost :: ptr_container_detail :: reversible_ptr_container ,CloneAllocator>: :引用boost :: ptr_sequence_adapter :: :: operator [](typename boost :: ptr_container_detail :: reversible_ptr_container Nav 2010-10-23 10:06:50

+0

[continue ...],CloneAllocator> size_type)[with T = Derived,VoidPtrSeq = std :: vector >,CloneAllocator = boost :: heap_clone_allocator]:斷言'n < this-> size()'失敗。 Aborted(核心轉儲) – Nav 2010-10-23 10:07:20