在写我的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 ++参考网站没有帮助我解释它)?
答案 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);
}