Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 智能指针/编码模式的名称_C++_Design Patterns_Boost_Qt4_Smart Pointers - Fatal编程技术网

C++ 智能指针/编码模式的名称

C++ 智能指针/编码模式的名称,c++,design-patterns,boost,qt4,smart-pointers,C++,Design Patterns,Boost,Qt4,Smart Pointers,最近,我经常遇到需要类似于此数据结构的东西的情况 限制:C++03标准 有几个节点类,其中每个节点持有对同一个“数据”(类、结构,无论什么-动态分配)实例的节点引用(思考共享的) 还有一个“Root”或“master”节点/类,它持有对相同“数据”的RootDataRef引用(这一次,考虑弱的ptr) 当所有节点被销毁时,数据也被销毁,RootDataRef被设置为0/NULL。也就是说,NodeDataRef的行为类似于shared\u ptr和RootDataRef的行为类似于weak\u

最近,我经常遇到需要类似于此数据结构的东西的情况

限制:C++03标准


  • 有几个
    节点
    类,其中每个
    节点
    持有对同一个“
    数据
    ”(类、结构,无论什么-动态分配)实例的
    节点引用(思考
    共享的
  • 还有一个“
    Root
    ”或“master”节点/类,它持有对相同“
    数据
    ”的
    RootDataRef
    引用(这一次,考虑
    弱的ptr
  • 当所有
    节点
    被销毁时,
    数据
    也被销毁,
    RootDataRef
    被设置为
    0
    /
    NULL
    。也就是说,
    NodeDataRef
    的行为类似于
    shared\u ptr
    RootDataRef
    的行为类似于
    weak\u ptr
  • 但是根节点可以强制销毁数据,即使仍有活动的
    NodeDataRef
    s。在这种情况下,所有指向数据的
    NodeDataRef
    s都被设置为
    NULL
    /
    0
    RootDataRef
    也被设置为
    0
    /
    NULL

  • 即,
    弱\u ptr
    可强制销毁所有链接的
    共享\u ptr

  • 此模式/智能指针类型是否有名称
  • 如何使用Boost或Qt4快速实现这一点?(“快速”表示无需编写类来维护引用列表)
  • 此模式/智能指针类型是否有名称

    据我所知,不,这不是一个具有常用名称的典型所有权模式

    如何使用Boost或Qt4快速实现这一点?(“快速”表示无需编写类来维护引用列表)

    对于这个用例没有预先打包的所有权策略,因为这会破坏共享所有权的观点。如果存在指向给定对象的多个共享指针,根据定义,这些共享指针必须使该对象保持活动状态。如果给我一个共享指针,这就保证了对象在我释放它之前是存在的

    如果您希望一个主对象能够命令销毁指向它的对象,而不管其他对象是否持有指向它的共享指针,那么您必须想出一些单独的机制,让它命令指向该对象的共享指针的所有持有者释放它

    更新:

    尽管存在“黑客”解决方案可以“快速”完成这项工作,但我不建议您使用其中任何一种。这种模式非常非典型,以至于当有人阅读您的代码时(包括几个月后的您),您希望它是明显的


    您的意图应该通过主对象和其他所有者之间的显式通信模式来明确,而不是隐藏在包装器、自定义删除器或其他任何东西中。

    您可以使用
    共享\u ptr
    弱\u ptr
    其中
    T=scoped\u ptr
    。假设您可以使用操作符new创建
    数据
    实例)

    应使用
    make_shared(新数据(…))分配
    shared_ptr

    根弱\u ptr可以通过调用
    root.lock().reset()

    模板
    结构RootHandle:public boost::weak\u ptr
    {
    typedef boost::弱_ptr弱_type;
    typedef boost::shared_ptrstrong_type;
    RootHandle(){}
    RootHandle(const弱类型和impl)
    :弱_型(impl){
    T*get()常量
    {
    强_类型x=锁();
    返回(x)→x->get():0;
    }
    无效重置()
    {
    强_类型x=锁();
    if(x)
    x->reset();
    }
    };
    模板
    结构NormalHandle:public boost::shared\u ptr
    {
    公众:
    typedef boost::shared_ptrstrong_type;
    NormalHandle(){}
    NormalHandle(常量强类型和impl)
    :强_类型(impl){
    T*get()常量
    {
    boost::scoped_ptr*ppx=strong_type::get();
    返回(0!=ppx)?ppx->get():0;
    }   
    };
    
    新NormalHandles的初始化如下所示:


    normalhandlehandle1(boost::make_shared(新数据(4,3,“abc”))

    我不知道您为什么要这样做,但这里有一个(非常)黑客的解决方案,它还需要在每次访问
    NodeDataRef
    时运行一些额外的代码(理想情况下作为该类的方法)

    数据一起创建sentinel对象。给
    RootDataRef
    一个拥有它的引用,给所有节点一个弱引用。然后,在每次访问
    NodeDataRef
    之前,检查对哨兵的弱引用是否仍然有效。要强制从
    根目录
    中删除,请删除对sentinel所拥有的引用,从而导致
    节点数据库中的所有弱引用无效。

    一种易于实现(但不是最有效)的方法是使用双共享ptr层:
    共享\u ptr
    根目录将有一个指向该目录的弱指针,当您需要强制销毁时,您将重置内部共享的\u ptr数据(在锁定下执行!)

    所有其他节点都将正常使用它,但在使用它之前必须检查内部共享\u ptr的有效性。

    没有人给出特定于Qt的答案(奇怪?),因此我将对此进行分析,尽管我对共享指针类有点粗糙

    似乎可以将
    RootDataRef
    生成为一个节点,并从中派生节点。创建第一个
    NodeDataRef
    后,将
    RootDataRef
    降级为使用。这样,当您删除所有的
    NodeDataRef
    s时,原始指针将被删除,而
    RootD将被删除
    
     +-----+--------------+               +----+
     |node0| NodeDataRef ->-------------->|data|
     +-----+--------------+               +----+
     +-----+--------------+                ^^ ^
     |node1| NodeDataRef ->----------------+| |
     +-----+--------------+                 | |
     +-----+--------------+                 | |
     |node2| NodeDataRef ->-----------------+ |
     +-----+--------------+                   |
                                              |
     +-----+--------------+                   |
     |root | RootDataRef ->-------------------+
     +-----+--------------+              
    
    template <typename T>
    struct RootHandle : public boost::weak_ptr< boost::scoped_ptr<T> >
    {
        typedef boost::weak_ptr< boost::scoped_ptr<T> > weak_type;
        typedef boost::shared_ptr< boost::scoped_ptr<T> > strong_type;
    
        RootHandle() {}
        RootHandle(const weak_type& impl)
            :weak_type(impl) {}
    
    
        T* get() const
        {
            strong_type x = lock();
            return (x) ? x->get() : 0;
        }
    
        void reset()
        {
            strong_type x = lock();
            if (x)
                x->reset();
        }
    };
    
    template <typename T>
    struct NormalHandle : public boost::shared_ptr< boost::scoped_ptr<T> >
    {
    public:
        typedef boost::shared_ptr< boost::scoped_ptr<T> > strong_type;
    
        NormalHandle() {}
        NormalHandle(const strong_type& impl)
            :strong_type(impl) {}
    
        T* get() const
        {
            boost::scoped_ptr<T>* ppx = strong_type::get();
            return (0 != ppx) ? ppx->get() : 0;
        }   
    };