![](/img/trans.png)
[英]How push_back unique_ptr parameter onto vector of shared ptrs
[英]How do you push_back a shared_ptr variable to a vector of shared_ptrs in C++?
我是 C++ 的初學者,具有 Python、Java 和 JS 的背景,所以在指針方面我仍在學習中。
我有一個共享指針向量。 在另一個 function 中,我將一個共享指針分配給一個變量並將其添加到向量中。 如果我在 function 退出后嘗試訪問添加的元素,則會發生分段錯誤:
class Bar
{
private:
std::vector<std::shared_ptr<Foo>> fooVector;
}
void Bar::addToFoo()
{
std::shared_ptr<Foo> foo (new Foo(…));
fooVector.push_back(foo);
}
void Bar::otherMethod()
{
// this method gets called sometime after addToFoo gets called
…
fooVector[anIndex]->baz(); // segfaults
…
}
但是,如果 push_back 是一個共享指針而不是一個變量,它就可以工作。
// this works:
fooVector.push_back(std::shared_ptr<Foo>(new Foo(…)));
// this segfaults:
std::shared_ptr<Foo> foo (new Foo(…));
fooVector.push_back(foo);
我相信這是因為foo
變量在addToFoo
function 退出時被刪除(如果我錯了請糾正我)。 如何將shared_ptr
變量push_back
到 C++ 中的shared_ptrs
vector
?
為什么使用變量
雖然直接將shared_ptr
推入向量而不使用變量是可行的,但我更喜歡使用變量來做到這一點:
std::shared_ptr<Rider> rider;
switch (iProcessorModesParam)
{
case PEAKS_MODE:
rider = std::shared_ptr<Rider>(new PeaksRider(…));
break;
case RMS_MODE:
rider = std::shared_ptr<Rider>(new RMSrider(…));
break;
}
volumeRiders.push_back(rider);
PeaksRider 和 RMSrider 是 Rider 的子類。 我想將 Rider 的所有子類型存儲在相同的 Riders 向量中。 我了解到,將 Rider 的子類型添加到 Riders 的向量中是行不通的,需要指針才能實現這種多態性:
std::vector<Rider> // doesn’t work with subtypes
std::vector<*Rider>
std::vector<std::shared_ptr<Rider>>
擁有std::shared_ptr<Rider> rider;
變量避免為每種類型的 Rider 重復.push_back(…)
代碼。
不是分配共享指針,而是用戶reset
方法。
rider.reset(new PeaksRider(…));
除此之外,您的代碼片段對我來說似乎沒問題。
段錯誤可能是由於索引變量(可能超出范圍)引起的。 我建議您使用.at(index)
從 vector 訪問指針並將該部分代碼包裝在try..catch
塊中,看看真正的錯誤是什么。
而關於...
我相信這是因為 foo 變量在 addToFoo function 退出時被刪除(如果我錯了請糾正我)。
這不是真的,share_ptrs 使用本地計數器來獲取 #of 引用。 一旦您將指針推向向量,計數器就會增加到 2,並且在控制退出 function 之后,計數器就會減少到 1。因此,您的 object 尚未被銷毀。
創建共享指針實例,將其存儲在變量中,然后對向量執行 push_back 沒有問題。 只要您在調用“otherMethod”時使用的索引有效,您的代碼就應該沒問題。 但是,我對您的代碼有一些建議:
我剛剛寫了一個小片段,您可以測試它來說明我剛才提到的內容:
#include <iostream>
#include <vector>
#include <memory>
#include <cassert>
class Foo
{
public:
int data = 0;
};
class Bar
{
public:
void addNewFoo(int d)
{
std::shared_ptr<Foo> foo(new Foo());
foo->data = d;
fooVector.push_back(foo);
}
void addNewFooImproved(int d)
{
auto foo = std::make_shared<Foo>();
foo->data = d;
fooVector.push_back(foo);
}
void printFoo(int idx)
{
assert(idx < fooVector.size());
std::cout << fooVector[idx]->data << std::endl;
}
private:
std::vector<std::shared_ptr<Foo>> fooVector;
};
int main()
{
Bar b;
b.addNewFoo(10);
b.addNewFoo(12);
b.addNewFooImproved(22);
b.printFoo(1);
b.printFoo(2);
b.printFoo(0);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.