• shared_ptr模版推导的问题


    问题描述

    今天在帮同事解决问题时,发现了这个比较有意思的现象,特记录下来备忘。
    问题是这样的,同事开发的是应用程序动态库模块,通过应用的框架中以接口方式供外部使用。然后他想对这些接口生命周期进行控制,从语法角度上约束使用者使用的手段。因此他作出了以下修改:
    1.增加接口的析构函数,并将析构函数设定为保护级别
    2.返回接口的函数用shared_ptr的形式返回

    具体代码示例

    // 测试接口
    struct IAA
    {
        virtual void Release() = 0;
    protected:
        virtual ~IAA(){}
    };
    
    // 对象删除器
    struct HelpDeleteIAA
    {
        void operator()(IAA* pAA)
        {
            if (NULL!=pAA)
            {
                pAA->Release();
            }
        }
    };
    
    class CAA : public IAA
    {
    public:
        CAA()
        {
        }
        virtual ~CAA()
        {
        }
        virtual void Release()
        {
            delete this;
        }
    };
    
    typedef std::tr1::shared_ptr<IAA> SPIAA;
    
    // 测试创建
    SPIAA helpIAA(bool bFlag)
    {
        if (bFlag)
        {
            return SPIAA(new CAA, HelpDeleteIAA());
        }
        return SPIAA(static_cast<IAA*>(NULL));
    }
    
    int main()
    {
        SPIAA spAA = helpIAA(); // 测试使用
        return 0;
    }
    

    写完以后兴冲冲的一编译,傻眼了,提示是不能访问IAA::~IAA()的析构接口。可是在代码中明显指定了删除器啊?百思不得其解。。。

    问题原因分析

    经过调试后发现问题出现在helpIAA()的函数中,由于智能指针shared_ptr()是一个模版,满足模版推导的过程,而在helpIAA()函数中用到了两种函数构造原型,猜测可能是编译过程中对该模版推导顺序影响了最后产生的结果。

    解决方案

    将helpIAA()函数的返回代码

    return SPIAA(static_cast<IAA*>(NULL));
    

    修改为

    return SPIAA(static_cast<IAA*>(NULL), HelpDeleteIAA());
    

    然后执行编译,编译器顺利编译通过了。

    总结

    以上的问题原因推断只是我个人的一点看法,如果不正确的地方欢迎各位斧正。

  • 相关阅读:
    父页面与子页面间相互传值
    PS常用技能综合
    JS 提交form表单
    html实体字符
    js基础
    Delegate模式
    IOS-基础知识
    测试工具综合
    [Linux] Nginx 提供静态内容和优化积压队列
    [Linux] Nginx响应压缩gzip
  • 原文地址:https://www.cnblogs.com/sanghg/p/4073465.html
Copyright © 2020-2023  润新知