指针调整大小的矢量



在我的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++ 参考站点没有帮助我解释它)?

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

相关内容

  • 没有找到相关文章

最新更新