std :: shared_ptr由此构造

时间:2017-09-12 22:46:58

标签: c++ c++11 smart-pointers

我想将类的所有对象添加到class A : public std::enable_shared_from_this<A> { public: A(); ~A(); static std::map<uint32_t, std::shared_ptr<A>> getObjects(); private: static uint32_t counter; uint32_t id; static std::map<uint32_t, std::shared_ptr<A>> objects; }; 。由于我不想复制对象,我尝试使用这样的智能指针来解决方法:

Class.h

A::A()
{
    id = counter++;
    std::shared_ptr<A> ptr = std::make_shared<A>();
    objects[id] = ptr->shared_from_this();
}

A::~A()
{
    objects.erase(id);
}

std::map<uint32_t, std::shared_ptr<A>> A::getObjects()
{
    return objects;
}

uint32_t A::counter=0;

std::map<uint32_t, std::shared_ptr<A>> A::objects;

Class.cpp

int main(){
    A a;
    A b;
    auto objects = A::getObjects();
}

这个编译很好但是当试图像这样使用它时

A::A()
{
    id = counter++;
    std::shared_ptr<A> ptr(this);
    objects[id] = ptr->shared_from_this();
}

我得到了

  

分段错误:11`

如果我尝试将构造函数更改为

std::shared_ptr<A>

我得到了

  

释放的指针未分配

我基本上需要从this构建一个SELECT SUM(DETA_MTO_CUOTA) MONTO, DETA_NACIONALIDAD as NAC, DETA_CEDULA as CEDULA, DETA_CODIGO as CODIGO, DETA_SUB_CODIGO as SUBCODIGO, DETA_AJUN_ANO_FISCAL as FISCAL FROM SRH_DETALLE_AJUS WHERE DETA_AJUN_NRO = 6351 AND DETA_TIPO_REG = 'A' AND DETA_SUB_CODIGO = 50 GROUP BY DETA_NACIONALIDAD, DETA_CEDULA, DETA_CODIGO, DETA_SUB_CODIGO, DETA_AJUN_ANO_FISCAL ,但无法让它工作。

3 个答案:

答案 0 :(得分:1)

您无法获得指向不受共享指针管理的对象的拥有共享指针。

自动存储对象的生命周期可能没有由共享指针管理其生命周期。

通常,您的设计无法完成,因为对象和对象的生命周期由创建对象的代码控制,而不是对象本身。

智能pImpl包装器可以使对象的内容具有单独的智能指针确定的生命周期。但即使存在共享指针解决方案也是非法的,因为销毁地图可以杀死最后一个共享指针,然后该指针尝试重新输入地图代码并将其删除。这是未定义的行为。

弱指针映射内容,基于pImpl的包装器,取消注册实例的智能删除器以及其他工作的混合可能有效。这超出了SO答案的范围。

您必须了解如何管理对象生命周期,弱ptrs的工作方式,替代删除器,基于pImpl的值类型以及无数其他主题。祝你好运。

答案 1 :(得分:1)

您的原始代码有堆栈溢出:

A::A()
{
    id = counter++;
    std::shared_ptr<A> ptr = std::make_shared<A>();
    objects[id] = ptr->shared_from_this();
}

您无条件地在A的构造函数中构建A

你接受的尝试也不起作用:

A::A()
{
    id = counter++;
    std::shared_ptr<A> ptr(this);
    objects[id] = ptr->shared_from_this();
}

shared_from_this()仅在此对象的生命周期由std::shared_ptr管理时有效。

您可以选择几种方式。你可以使用静态工厂函数而不公开构造函数,但这对你的类来说是一个意想不到的设计。

对我来说,更清晰的设计是做类似于Pimpl模式的事情。您可以std::shared_ptr实现A的实际实现,并将功能包装在仅包含shared_ptr的对象中。

答案 2 :(得分:1)

如果您需要存储在全局映射中的类的所有实例,可以尝试以下操作:1)隐藏所有构造函数; 2)仅通过静态('工厂')方法创建新对象。在您的情况下,此方法可以返回shared_ptr(或者说,它可以返回引用,shared_ptr本身专用于全局映射;在这种情况下,您甚至可以使用unique_ptr)。