OnTheWay2012
埋葬昨天的我,迎来重生的我!
posts - 15,  comments - 89,  trackbacks - 0
周五晚上的时候在看Boost的源码的时候发现了shared_ptr有一个很好用的功能,该功能的代码示例如下:
boost::shared_ptr<int> pInt(new int(0));
if (pInt)
.
.
.
从上述代码中可以看出,shared_ptr能够模拟内置指针的功能。我很好奇shared_ptr是如何实现的这个功能,然后就找到了shared_ptr的源代码看了看,结果发现在VC9的编译环境下,shared_ptr不是采用重载bool操作符来实现的,为什么不采用重载bool操作符来实现呢?用一下代码说明:
//如果采用重载bool操作符的形式来实现的话,会存在以下的一些问题,这些问题可以总结为“在不该使用的地方使用了隐含的类型转换”
shared_ptr<int> pInt(new int(0));
int n = pInt;//如果采用重载布尔的方法,这句明显应该是错误的语句就会编译通过
那么,Boost采用的方法是什么方法呢?Boost所采用的方法的是:
 typedef T * (this_type::*unspecified_bool_type)() const;   //Ln 1

    
operator unspecified_bool_type() const // never throws  Ln2
{
        
return px == 0? 0&this_type::get; //Ln3
    }
当第一次看到这三行代码的时候,我被震惊了!
我看了半天都不知道这三行代码到底是什么意思!周五晚上我用baidu,google搜了半天,终于发现Ln1不就是自己以前用过的指向成员函数的指针吗?!我真蠢,看了半天还是没看明白。那么一个问题解决了,另外一个更无法理解的问题出现了:为什么在写下
if(pInt)
Ln2和Ln3所定义的函数会被调用!!!我找呀找,还是不明白!我问google呀,还是不明白!我问baidu呀,还是不明白!
这个问题,折磨了我两天,今天晚上的时候,有打开VC9,有一次看到这段代码,突然就明白了。
在Ln1定义了一个类型(指向成员函数指针);
在Ln2和Ln3定义了一个函数,该函数是一个类型转换函数,把shared_ptr,转换为一个指向成员函数的指针。
举一个简单的类型转换函数的例子:
class A
{
public:
     
operator int()
     
{
          
return 0;
     }

}


void Test(int a)
{
     cout
<<a<<endl;
}


void main()
{
     A a;
     Test(a);
//这里调用的是类型转换函数
}
至于为什么这种方法比重载bool好,是因为指向成员函数的指针很少能够被编译器用来做隐含的类型转换。

现在终于明白了上面的代码。虽然代码里面的技术我都用过,但是当时为什么没有像明白呢?!
我分析原因有两条:
1. 最近好久没有写过代码,生疏了。这是次要原因。
2.对C++缺乏了解。这是主要原因。


在解决这个问题的时候用google搜到了一个老外发的贴,大致内容如下:
每当我觉得对C++有所了解或者掌握它的秘密的时候,我总发现一些改变我看发的事情。
....

另外一个老外回答的时候用了一句话。I know the feelings.

现在,我终于也有第一个老外的感觉了。
posted on 2010-12-05 18:56 OnTheWay 阅读(2285) 评论(4)  编辑 收藏 引用 所属分类: 个人感悟

FeedBack:
# re: Why I am so stupid?
2010-12-05 23:19 | right
最近不知道怎么搞的,如果有人跟我研究这些C++的高级语法高级特性时,我总是有种想泼冷水的冲动。不过想想自己也是这么走过来的,也就逐渐释然了。  回复  更多评论
  
# re: Why I am so stupid?
2010-12-06 08:44 | Sosi
Boost 乃一大宝藏。。。  回复  更多评论
  
# re: Why I am so stupid?
2010-12-06 10:27 | 空明流转
写boost的人是挖空心思从Spec里面想抠出点东西拿来用。

那个令人发指的typeof更是连编译器bug都用上了。

你要是挖空心思,其实也是可以的。。。  回复  更多评论
  
# re: Why I am so stupid?
2010-12-13 17:53 | crossgate
不觉得这个是C++的高级语法特性,觉得是比较常规的,实用的特性。

如果if判断的时候,统一用 if (!pInt),会更合适。重载!操作符,会更容易,也更一般化一些。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理



<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(4)

随笔分类

随笔档案

友情连接

搜索

  •  

最新评论

阅读排行榜

评论排行榜