免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11626 | 回复: 9
打印 上一主题 下一主题

webkit & WTF 源码 的 几个困惑 (欢迎waterloop老弟) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-16 15:41 |只看该作者 |倒序浏览
在 WTF 库中:

nonecopable.h

  1. #ifndef WTF_Noncopyable_h
  2. #define WTF_Noncopyable_h

  3. // We don't want argument-dependent lookup to pull in everything from the WTF
  4. // namespace when you use Noncopyable, so put it in its own namespace.

  5. namespace WTFNoncopyable {

  6.     class Noncopyable {
  7.         Noncopyable(const Noncopyable&);
  8.         Noncopyable& operator=(const Noncopyable&);
  9.     protected:
  10.         Noncopyable() { }
  11.         ~Noncopyable() { }
  12.     };

  13. } // namespace WTFNoncopyable

  14. using WTFNoncopyable::Noncopyable;

  15. #endif // WTF_Noncopyable_h
复制代码


拷贝构造和赋值构造搞成private, 然后让其他类派生 ,派生类应该没法调用拷贝构造和赋值构造了吧,
可这么做有什么意义,有什么具体的应用场景么?哪位能举个小case么?


ownptr.h


  1. #ifndef WTF_OwnPtr_h
  2. #define WTF_OwnPtr_h

  3. #include <algorithm>
  4. #include <wtf/Assertions.h>
  5. #include <wtf/Noncopyable.h>

  6. namespace WTF {

  7.     template <typename T> class OwnPtr : Noncopyable {
  8.     public:
  9.         explicit OwnPtr(T* ptr = 0) : m_ptr(ptr) { }
  10.         ~OwnPtr() { safeDelete(); }

  11.         T* get() const { return m_ptr; }
  12.         T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }

  13.         void set(T* ptr) { ASSERT(!ptr || m_ptr != ptr); safeDelete(); m_ptr = ptr; }
  14.         void clear() { safeDelete(); m_ptr = 0; }

  15.         T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
  16.         T* operator->() const { ASSERT(m_ptr); return m_ptr; }

  17.         bool operator!() const { return !m_ptr; }

  18.         // This conversion operator allows implicit conversion to bool but not to other integer types.
  19.         typedef T* (OwnPtr::*UnspecifiedBoolType)() const;
  20.         operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::get : 0; }

  21.         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }

  22.     private:
  23.         void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete m_ptr; }

  24.         T* m_ptr;
  25.     };
  26.    
  27.     template <typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) { a.swap(b); }

  28.     template <typename T> inline T* getPtr(const OwnPtr<T>& p)
  29.     {
  30.         return p.get();
  31.     }

  32. } // namespace WTF

  33. using WTF::OwnPtr;

  34. #endif // WTF_OwnPtr_h
复制代码


void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete m_ptr; }
这句怎么这么怪异?

[ 本帖最后由 windyrobin 于 2009-7-16 15:48 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-07-16 17:55 |只看该作者
关于问题1,可以看一下下面这个链接的介绍。
http://blog.csdn.net/alai04/archive/2006/01/13/577798.aspx

问题2:

void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete m_ptr; }

这个条件应该永远都是真的,如果是假的,那么将会出现编译错误。所以这个地方应该是一个用于编译的技巧而已。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
3 [报告]
发表于 2009-07-16 23:12 |只看该作者

回复 #1 windyrobin 的帖子

下面的OwnPtr不正好是一个case么~~~

如果有个类, 不希望被复制和赋值, 就可以:
class i_can_not_be_copied {
   i_can_not_be_copied(const i_can_not_be_copied&);
   i_can_not_be_copied& operator=(const i_can_not_be_copied&);
public:
   // ...
};

有人嫌这样写着比较麻烦, 就搞了这么一个Noncopyable出来……
有了这么一个自己不能被复制、赋值的类,只要简单的继承它, 自己也就不能被复制赋值了。
然后就有了这么一种比较方便的写法:
class i_can_not_be_copied : Noncopyable { };


也有人搞过宏:
#define DISABLE_COPY_ASSIGNMENT(cls) \
private:                                                       \
    cls(const cls&);                                        \
    cls& operator=(const cls&);

class i_can_not_be_copied {
    DISABLE_COPY_ASSIGNMENT(i_can_not_be_copied)
};


不过我还是觉得老老实实写出来比较好。。。


C++0x打算支持:
class i_can_not_be_copied {
    i_can_not_be_copied(const i_can_not_be_copied&) = delete;
    i_can_not_be_copied& operator=(const i_can_not_be_copied&) = delete;
};

如果真支持delete的这种用法, 明确写出来就更有优势:如果自身成员或友元使用了这些函数, 编译时就会发现错误, 而不会延迟到链接时。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
4 [报告]
发表于 2009-07-16 23:30 |只看该作者

回复 #1 windyrobin 的帖子

void safeDelete() { typedef char known[sizeof(T) ? 1 : -1]; if (sizeof(known)) delete m_ptr; }

这个……    不明白意图……

sizeof(T)如果求得出, 显然是>=1的,恒真。
如果求不出, 就是一个不完全类型, 编译就会错, 也就不存在-1的情况了。

如果真能有什么类型的sizeof为0(可是,有这种情况吗???), 导致known维度为-1 , 也是会错。
"负数不能作为数组维度"。 这是一个常用的实现编译时assertion手法。

windows某个头文件中就有这样的宏:
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]

如果e(compile-time expression)为真, 就定义了一个大小为1的char数组类型,__C_ASSERT__。
如果为假, 就出现编译错误。

<<modern c++ design>>中还想了很多办法, 让编译器报出的错更明显, 而不是一个“负数不能作为维度”。
boost里面也有这么个东西, 没怎么看过……

我还是喜欢明确写出来:
{ char assume[ expression? 1:-1]; (void) assume; }



后面这个也很费解:
if (sizeof(known))
即使编译不出错, 条件测试也是还是恒真……

根据known这么名字, 大概猜是要检测不完全类型, 让不完全类型在 known[ sizeof(T)?1:-1 ]这里就出现错误。
然而对于不完全类型, delete 本来就是不允许的,  不知道safeDelete从何说起……


总之, 这些代码除了让编译器报错多一些——本来只有类似"不完全类型不能delete""不能访问析构函数"……, 现在可以多出"不完全类型不能sizeof" "数组维度不能为负数"  —— 没看出有什么用处……


问代码作者吧

[ 本帖最后由 OwnWaterloo 于 2009-7-16 23:33 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2009-07-17 10:20 |只看该作者
感谢 NeteLife  ,链接文章 很好狠强大,受益匪浅!

感谢 ownwaterlop老弟 ,讲解总是 那么详细精辟!

还有没 牛人 指点 下 第二个问题呵?

论坛徽章:
0
6 [报告]
发表于 2009-07-17 18:46 |只看该作者
呵呵 ,WTF 是 apple 公司的啦,这个库还是不错的,
应该是借鉴了很多现代C++ 的编程技术,最主要的是,
它体积不大,仅有30个文件左右。

boost吧,那玩意太大了,前段时间下载过,貌似100多兆 ,下到半路就被我取消了!


比如它有 vector ,hashMap  、智能指针,systemAlloc ,spinlock等跨平台的实现!


WTF 可以当做 STL 的精简版和改进版来使用 ,能“嵌入” 到其他工程发布!
大名鼎鼎的webkit 就是基于WTF 构建的!

[ 本帖最后由 windyrobin 于 2009-7-17 18:54 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-07-17 20:21 |只看该作者
你好,
可否给一下wtf源代码的官方网址?
我想看看它的代码
网上google和百度了好久竟然没找到。。。只看到webkit中对它的引用。。

boost源代码看过几个库的实现
感觉boost太庞大了。。。。

[ 本帖最后由 ayw215 于 2009-7-17 20:22 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2009-07-17 20:50 |只看该作者
原帖由 ayw215 于 2009-7-17 20:21 发表
你好,
可否给一下wtf源代码的官方网址?
我想看看它的代码
网上google和百度了好久竟然没找到。。。只看到webkit中对它的引用。。

boost源代码看过几个库的实现
感觉boost太庞大了。。。。


网上信息确实很少,附件为我从webkit中提取的,压缩后仅100多k!

wtf.rar

100.07 KB, 下载次数: 147

wtf

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
9 [报告]
发表于 2009-07-26 23:03 |只看该作者

回复 #5 windyrobin 的帖子

大哥, 查到那段诡异代码的含义了没???

论坛徽章:
0
10 [报告]
发表于 2011-01-17 16:15 |只看该作者
依哥看来:主要看这个sizeof()
   牛人说:"sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。"
所以我看来是这里是可能是防止delete 掉那些东西.^_^.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP