简体   繁体   English

如何将 shared_ptr 变量 push_back 到 C++ 中的 shared_ptr 向量?

[英]How do you push_back a shared_ptr variable to a vector of shared_ptrs in C++?

I'm a C++ beginner with a background in Python, Java, and JS, so I'm still learning the ropes when it comes to pointers.我是 C++ 的初学者,具有 Python、Java 和 JS 的背景,所以在指针方面我仍在学习中。

I have a vector of shared pointers.我有一个共享指针向量。 Inside of a different function, I assign a shared pointer to a variable and add it to the vector.在另一个 function 中,我将一个共享指针分配给一个变量并将其添加到向量中。 If I try to access the added element after that function exits, a segmentation fault happens:如果我在 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
    …
}

But, if push_back a shared pointer and not a variable, it works.但是,如果 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);

I believe it happens because the foo variable gets deleted when the addToFoo function exits (correct me if I'm wrong).我相信这是因为foo变量在addToFoo function 退出时被删除(如果我错了请纠正我)。 How do you push_back a shared_ptr variable to a vector of shared_ptrs in C++?如何将shared_ptr变量push_back到 C++ 中的shared_ptrs vector


Why Use A Variable为什么使用变量

Though pushing shared_ptr s to vectors directly without variables works, I prefer to use variables in order to do this:虽然直接将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 and RMSrider are subclasses of Rider. PeaksRider 和 RMSrider 是 Rider 的子类。 I want to store all subtypes of Rider in the same vector of Riders.我想将 Rider 的所有子类型存储在相同的 Riders 向量中。 I learned that adding subtypes of Rider to a vector of Riders doesn't work and pointers are needed in order to achieve this kind of polymorphism:我了解到,将 Rider 的子类型添加到 Riders 的向量中是行不通的,需要指针才能实现这种多态性:

std::vector<Rider> // doesn’t work with subtypes

std::vector<*Rider>
std::vector<std::shared_ptr<Rider>>

Having the std::shared_ptr<Rider> rider;拥有std::shared_ptr<Rider> rider; variable avoids repeating the .push_back(…) code for each type of Rider.变量避免为每种类型的 Rider 重复.push_back(…)代码。

Instead of assigning shared pointer, user reset method.不是分配共享指针,而是用户reset方法。

rider.reset(new PeaksRider(…));

other that this, your code snippets seems to okay to me.除此之外,您的代码片段对我来说似乎没问题。

segfault may have caused because of the index variable ( which may be out of range).段错误可能是由于索引变量(可能超出范围)引起的。 i suggest you to use .at(index) for accessing pointer from vector and wrap that part of code in a try..catch block and see what is the real error.我建议您使用.at(index)从 vector 访问指针并将该部分代码包装在try..catch块中,看看真正的错误是什么。

And regarding...而关于...

I believe it happens because the foo variable gets deleted when the addToFoo function exits (correct me if I'm wrong).我相信这是因为 foo 变量在 addToFoo function 退出时被删除(如果我错了请纠正我)。

This is not true, share_ptrs use a local counter for #of references.这不是真的,share_ptrs 使用本地计数器来获取 #of 引用。 as soon as you pushed the pointer to vector the counter gets incremented to 2 and event after control exits the function the counter is decremented to 1. so, your object is not destroyed yet.一旦您将指针推向向量,计数器就会增加到 2,并且在控制退出 function 之后,计数器就会减少到 1。因此,您的 object 尚未被销毁。

There is no problem on creating a shared pointer instance, storing it in a variable, and doing a push_back to a vector after that.创建共享指针实例,将其存储在变量中,然后对向量执行 push_back 没有问题。 Your code should be fine as long as the index that you use when calling "otherMethod" is valid.只要您在调用“otherMethod”时使用的索引有效,您的代码就应该没问题。 However, I have a couple of suggestions for your code:但是,我对您的代码有一些建议:

  • When you create a shared_ptr, it is highly recommended to do it through "std::make_shared" to ensure the safety and correctness of your code in all situations.当您创建一个 shared_ptr 时,强烈建议通过“std::make_shared”来创建,以确保您的代码在所有情况下的安全性和正确性。 In this other post you will find a great explanation: Difference in make_shared and normal shared_ptr in C++在另一篇文章中,您会找到一个很好的解释: Difference in make_shared and normal shared_ptr in C++
  • When accessing positions of a vector using a variable that may contain values that would cause an out-of-bounds access (which usually leads to segmentation faults) it is a good practice to place asserts before using the vector, so you will detect these undesired situations.当使用可能包含会导致越界访问(通常会导致分段错误)的值的变量访问向量的位置时,最好在使用向量之前放置断言,这样你就会检测到这些不需要的情况。

I just wrote a small snippet that you can test to illustrate what I just mentioned:我刚刚写了一个小片段,您可以测试它来说明我刚才提到的内容:

#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.

相关问题 如何将push_back unique_ptr参数推到共享ptrs的向量上 - How push_back unique_ptr parameter onto vector of shared ptrs C ++-将auto_ptrs放在shared_ptr向量中 - C++ - Putting auto_ptrs in a shared_ptr vector 从向量中删除 shared_ptr 时从 unordered_map 中删除 shared_ptrs(模拟) - deleting shared_ptrs from unordered_map when deleting shared_ptr from vector ( simulatiously) C ++如何在shared_ptrs的向量中存储多个类型? - C++ How can I store multiple types in an vector of shared_ptrs? 当想要push_back向量列表时,shared_ptr的向量导致错误:“没有重载函数的实例” - Vector of shared_ptr resulting in error: “no instance of overloaded function” when wanting to push_back vector list 派生类的Push_back shared_ptr - Push_back shared_ptr of derived class 通过类析构函数中的reset成员shared_ptrs解决C++11 shared_ptr循环引用? - Solve C++11 shared_ptr cycle reference through reset member shared_ptrs in class destructor? 将 boost::shared_ptrs 的向量的 std::vector 从 C++ 传递到 Python 时出现问题 - Problems passing a std::vector of vector of boost::shared_ptrs from C++ to Python 如何将字符串推送到 shared_ptr 的向量中? - How to push a string into a vector of shared_ptr? C++类的shared_ptr向量 - Vector of shared_ptr of an class C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM