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());
然后执行编译,编译器顺利编译通过了。
总结
以上的问题原因推断只是我个人的一点看法,如果不正确的地方欢迎各位斧正。
shared_ptr模版推导的问题的更多相关文章
- C++ Template之函数模版
函数模版的定义: template <typename T> T const& max(const T& a,const T b) { return a > b ? ...
- Effective Modern C++翻译(7)-条款6:当auto推导出意外的类型时,使用显式的类型初始化语义
条款6:当auto推导出意外的类型时,使用显式的类型初始化语义 条款5解释了使用auto来声明变量比使用精确的类型声明多了了很多的技术优势,但有的时候,当你想要zag的时候,auto可能会推导出了zi ...
- C++ Template之类模版
类模版的定义和声明都和函数模版类似: 代码如下: template <typename T> class Stack { public: void push(const T&); ...
- 一个适用于层级目录结构的makefile模版
今天写了个层次化的Makefile模版,用来自动化编译项目,这个模版应当包含以下功能: 适用于层次化结构,Makefile主要内容都放在顶层目录下的Makefile.env中,子层Makefile包含 ...
- 理解shared_ptr<T> ---2
1.引用计数字段不能放在资源管理类中.我们的解决办法是,把引用计数和资源绑在一起,进行二次封装.但是这样存在一个大问题,不同类型的资源管理类不能兼容.也就是说,shared_ptr<Dog> ...
- c++ lambda返回类型自动推导的一些需要注意的地方
一句话,lambda返回类型自动推导走的是auto,而不是decltype,注意. class ObjectA { public: ObjectA() { val_ = ++g; } ObjectA( ...
- [C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化
[C++ 2011 STL (VS2012 Update4) 源代码阅读系列(2)]熟悉一些宏定义和模版偏特化或叫模版专门化 // point_test.cpp : 知识点练习和测试,用于单步调试,跟 ...
- Cocos2d-x3.0模版容器具体解释之二:cocos2d::Map<K,V>
1.概述: 版本号: v3.0 beta 语言: C++ 定义在 "COCOS2DX_ROOT/cocos/base" 路径下的 "CCMap.h" 的头文件里 ...
- 智能指针auto_ptr & shared_ptr
转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...
随机推荐
- [学习OpenCV攻略][011][显示图片]
学习资料: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html 包含头文件 core.hpp:包含 ...
- SQL Server 使用问题解答(持续更新中)
问题一:sql server 2014不允许保存更改,您所做的更改要求删除并重新创建以下表 解答:工具-选项-不勾选组织保存要求重新创建表的更改,如下图确定.
- Spark算子--leftOuterJoin和rightOuterJoin
转载请标明出处http://www.cnblogs.com/haozhengfei/p/cb71cd3ac5d7965a2c61891659264d54.html leftOuterJoin和righ ...
- PHP defined() 函数
定义和用法 defined() 函数检查某常量是否存在. 若常量存在,则返回 true,否则返回 false. 语法 defined(name) 参数 描述 name 必需.规定要检查的常量的名称. ...
- LNMP状态管理命令
https://lnmp.org/faq/lnmp-status-manager.html LNMP状态管理命令: LNMP 1.2+状态管理: lnmp {start|stop|reload|res ...
- [SinGuLaRiTy] NOIP互测模拟赛
[SinGuLaRiTy-1045] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 源文件名 输入输出文件 时间限制 内存限制 淘气的cch ...
- HTML <form>标签
1.单选按钮 <html> <body> <form> 名: <input type="radio" name="myname& ...
- <%=pageCount %>
<%=pageCount %>,这里是指获取页面控件的值.
- P1144 最短路计数
P1144 最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶 ...
- JavaScript Date 时间对象方法
Date(日期/时间对象) Date 操作日期和时间的对象 Date.getDate( ) 返回一个月中的某一天 Date.getDay( ) 返回一周中的某一天 Date.getFullYear( ...