2014-03-03 64 views
0

在寫我的CFD代碼時,我遇到了一個指針向量的問題。 我打破它下降到下面的代碼,其表示的核心問題:指針調整大小的向量

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

class MyClass{ 
    public: 
     MyClass()        {} 
     MyClass(int i)       {_myVec.push_back(i);} 
     ~MyClass()        {_myVec.clear();} 
     const std::vector<int> myVec() const {return _myVec;} 
     std::vector<int> _myVec; 
    private: 
}; 


int main(){ 
    std::size_t size = 3; 
    std::vector< std::shared_ptr<MyClass> > myClass; 
    // add some elements with push_back 
    for(auto i = 0; i < size; i++){ 
     myClass.push_back(std::shared_ptr<MyClass>(new MyClass())); 
    } 
    for(auto i = 0; i < size; i++){ 
     myClass[i]->_myVec.push_back(i); 
    } 
    // print 
    for(auto i = 0; i < size; i++){ 
     for(auto j = 0; j < myClass[i]->myVec().size(); j++){ 
      std::cout << myClass[i]->myVec()[j] << " "; 
     } 
     std::cout << std::endl; 
    } 
    std::cout << std::endl; 
    myClass.clear(); 


    // add some elements with resize 
    myClass.resize(size, std::shared_ptr<MyClass>(new MyClass())); 
    for(auto i = 0; i < size; i++){ 
     myClass[i]->_myVec.push_back(i); 
    } 
    //print 
    for(auto i = 0; i < size; i++){ 
     for(auto j = 0; j < myClass[i]->myVec().size(); j++){ 
      std::cout << myClass[i]->myVec()[j] << " "; 
     } 
     std::cout << std::endl; 
    } 
    myClass.clear(); 
} 

爲這一段代碼的輸出中是下面。

0 
1 
2 

0 1 2 
0 1 2 
0 1 2 

第一部分正是我所期望的。第二部分是,讓我感到驚訝的是。 resize函數顯然首先構建類,並且將向量中的所有指針指向此類,而不是我認爲vector :: resize會做的操作,即爲每個元素調用new運算符,以便向量中的每個元素都指向到自己的對象。我真的不覺得這個行爲直覺和邏輯,如果我想有每個向量元素對同一指針,我會告訴編譯器,通過寫這樣的:

std::shared_ptr<MyClass> myTempclass = std::shared_ptr<MyClass>(new MyClass()) 
for(auto i = 0; i < size; i++){ 
    myClass.push_back(myTempclass); 
} 

可能有人請解釋爲什麼矢量在這種特殊情況下的行爲如此,或者鏈接到一個好的網站(C++參考網站並沒有幫我解釋它)?

回答

1

大小功能顯然首先構建類,比referes在載體中,這一類

所有指針其實也沒什麼,這並不完全發生了什麼。 當你在調用中寫入std::shared_ptr<MyClass>(new MyClass())時,你建立了類(和共享指針)。調整大小隻需要生成的參數,並執行它的邏輯。

調整大小的邏輯是通過複製參數創建任何必要的新值。複製shared_ptr會創建指向相同內容的新指針對象。這導致你看到的結果。

這是因爲如果你這樣寫:

std::shared_ptr<MyClass> ptr(new MyClass()); 
for(auto i = 0; i < size; i++) 
{ 
    myClass.push_back(ptr); 
} 
+0

所以我得到它的權利,當我說,調整大小操作員可以在載體之一,只有一個值(類,指針等等)複製到所有元素?這使得該功能比我想象的要靈活得多。 – user3184115

+0

是的,它需要創建的所有元素。它可能更適用於矢量直接包含對象的情況,比如'std :: vector ' – TheUndeadFish