矢量的指针调整大小

时间:2014-03-03 03:05:59

标签: c++ vector resize smart-pointers

在写我的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 个答案:

答案 0 :(得分:1)

  

resize函数显然首先构建类,然后将向量中的所有指针引用到这一类

实际上不,那不是发生了什么。 在调用中编写std::shared_ptr<MyClass>(new MyClass())时构建了类(和共享指针)。 resize只需获取生成的参数,然后使用该参数。

调整大小的逻辑是通过复制参数创建任何必要的新值。复制shared_ptr会创建指向同一事物的新指针对象。这样就可以看出结果。

好像你写过:

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