【问题标题】:Modifying value of object pointed by a shared pointer修改共享指针指向的对象的值
【发布时间】:2021-06-20 10:13:02
【问题描述】:

我最近开始使用共享指针,需要一些帮助。我有一个指向某些对象的共享指针向量 1。我需要构造另一个指向相同对象的共享指针向量 2,以便修改向量 2 会导致向量 2 的修改。 这就是我的代码的样子: 这很好用

class A
{
    public:
    int a;
    A (int x) {
      a = x;
    }
    int print() {
        return a;
    }
};

int main()
{
    shared_ptr<A> ab = make_shared<A>(100);
    cout<< ab->print();
    
    shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
    shared_ptr<vector<shared_ptr<A>*>> vec2 = make_shared<vector<shared_ptr<A>*>>();
    vec2->push_back(&(*vec1)[0]);
    for (shared_ptr<A>* obj : *vec2) {
        *obj = make_shared<A>(100);
    }
    cout << (*((*vec1)[0])).a;   // Prints 100
    return 0;
}

但这会在最后一行给出一个 SEGV,因为 vec1 没有填充:

class A
{
    public:
    int a;
    A (int x) {
      a = x;
    }
    int print() {
        return a;
    }
};

int main()
{   
    shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
    shared_ptr<vector<shared_ptr<A>>> vec2 = make_shared<vector<shared_ptr<A>>>();
    vec2->push_back((*vec1)[0]);
    for (shared_ptr<A> obj : *vec2) {
        obj = make_shared<A>(100);
    }
    cout << (*((*vec1)[0])).a;   // SIGSEGV
    return 0;
}

我想了解为什么 vec1 没有在第二个中填充,并且还想知道是否有其他方法可以做到这一点。谢谢!

【问题讨论】:

  • (*vec1)[0] 导致未定义的行为 - vec1 管理的向量为空,但您尝试访问第一个元素
  • 在第一个代码中,vec2 当前是指向 shared_ptr 的原始指针的向量,这没有任何意义 - 如果您打算将这些指向 vec1 的元素,它们将随时悬空@987654327 @ 重新分配内部存储。首先使用 shared_ptr 的全部原因之一是避免原始指针的问题,因此我强烈建议不要使用原始指针。为什么不让vec2vec1 具有相同的类型,并且两个向量的对应元素管理相同的目标?
  • 所以我的项目的要求是这样的——vec2 需要包含指向 vec1 中缺少的条目的指针。例如:如果 vec1 是 {a, _ , b, _ } 那么 vec2 需要包含指向 vec1 的第二个和第四个元素的指针。 vec1 是指向类对象的共享指针向量。如何以安全的方式做到这一点?
  • 在不调用vec1的任何成员函数的情况下,从外部改变vec1.size()并没有什么神奇的方法;如果这就是你要问的。您无法使用vec2 使vec1[0] 有效;在某些时候,以一种或另一种方式,您需要拨打vec1.push_back 或类似电话。鉴于此,目前尚不清楚您要达到的目标。也许您应该退后一步,描述您正在尝试解决的问题,而不是您想出但无法发挥作用的解决方案。另见:XY problem
  • 在示例中,vec1 的大小为 0。它在哪里以及如何变成大小为 10?

标签: c++ c++17 shared-ptr smart-pointers


【解决方案1】:

cmets 中描述的设置代码可以是:

#include <vector>
#include <memory>
#include <iostream>
using namespace std;

struct A
{
    int a;
    A(int a): a(a) {}
};

int main()
{   
    auto p_vec1 = make_shared<vector<shared_ptr<A>>>();
    auto p_vec2 = make_shared<vector<shared_ptr<A>>>();

    for (int i = 0; i < 100; ++i)
        p_vec1->push_back( make_shared<A>(i) );

    for (int i = 0; i < 50; ++i)
        p_vec2->push_back( (*p_vec1)[i * 2] ); 
    
    (*p_vec1)[2]->a = 213;
    std::cout << (*p_vec2)[1]->a << '\n';    // print 213

    return 0;
}

如果您不知道,“外部”shared_ptr 是不必要的,您可以只使用两个向量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2018-03-16
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多