C++03 3.9-10:

1

Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cv-qualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD-struct types, POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types.

 

As we all knows the pointer to member may not be cast into void* (GCC is OK but it's a special case anyway), according to the standrad we can store the pointer to member to a char buffer though. Unfortunately, the size of "pointer to member" is implementation defined, so we still need some hack for different compilers.

here's a table for sizeof(pointer to member) for some compilers

(http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Compiler            Options     Single  Multi   Virtual Unknown
    MSVC                        4       8       12      16
    MSVC            /vmg        16#     16#     16#     16
    MSVC            /vmg /vmm   8#      8#      --      8
    Intel_IA32                  4       8       12      16
    Intel_IA32      /vmg /vmm   4       8       --      8
    Intel_Itanium               8       12      16      20
    G++                         8       8       8       8
    Comeau                      8       8       8       8
    DMC                         4       4       4       4
    BCC32                       12      12      12      12
    BCC32           /Vmd        4       8       12      12
    WCL386                      12      12      12      12
    CodeWarrior                 12      12      12      12
    XLC                         20      20      20      20
    DMC small                   2       2       2       2
    medium                      4       4       4       4
    WCL small                   6       6       6       6
    compact                     6       6       6       6
    medium                      8       8       8       8
    large                       8       8       8       8

the original article implement each compiler's pointer to member mechanism, which I believe is insane, it's definitely not a good way to write portable codes.here's what I'm doing (code snippet).

所以pointer to member 可以被保存在byte array 里面再被解出来.这对于做delegate很有帮助.这是我目前使用的方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Delegate
{
public:
//per-compiler constant, or use a max enough size for all compilers
#if COMPILER == COMPILER_MSVC
    static const size_t MAX_POINTER2MEMBER_SIZE = 16;
#elif COMPILER == COMPILER_GNUC
    static const size_t MAX_POINTER2MEMBER_SIZE = 8;
#else
    static const size_t MAX_POINTER2MEMBER_SIZE = 20;
#endif
 
    void* mPtr;
    char  mMemberRaw[MAX_POINTER2MEMBER_SIZE ];
 
    //store the pointer to member to a byte buffer
    template <typename T>
    explicit Delegate(T* ptr, void (T::*func)(void*) )
    {
        assertsizeof(func) <= MAX_SIZE );
        ::memset(mMemberRaw, 0, MAX_SIZE);
        ::memcpy(mMemberRaw, &func, sizeof(func) );
    }
};
 
 
//invoke function: extract the "pointer to member" from the byte buffer
{
    ...
    typedef void (T::*TMemberFn)(void*);
    TMemberFn TFn = NULL;
    ::memcpy(&TFn, mMemberRaw, sizeof(TFn) );
    ( ((T*)mPtr)->*TFn )( data);
}

there's a very efficient way to do the delegate :

http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

他也是用模板函数,但不同的是把函数地址作为模板参数.本来打算改用这个方法的.但是唯一的缺点就是需要显式指定模板参数<>来实例化, 而构造函数只能通过TAD来套用模板参数,不能显式指定...所以他用的是一个静态模板函数来构造一个对象

1
delegate d = delegate::frommember<T,&T::func>( pOjb); //这样稍微有点恶心.

而我使用的方式虽然多了一个char[], 有一点点额外的内存开销和运行时开销,但是大多数情况下几乎可以忽略不计.

主要是可以通过Template Arugment Deduction 直接创建delegate, 比如:

1
Delegate d(pObj, &CLASS::function);

所以考虑了一下,决定暂时不用他的那种方法(用起来稍微不方便,但是效率非常高).以后看情况再考虑要不要改.

另外,作为一个C++程序猿, 个人觉得"数据绑定", "反射","代理",这些使用时尽量谨慎, 不可滥用. 除了在event/msg 和 UI/Tools的极少数地方要用以外,其他地方还是尽量不要用为好. 最近把数据绑定框架做了简单重构, 幸好用到的地方不多(主要是编辑器在用), 要不然重构就哭了. 目前还没有反射,暂时不需要, 以后需要时再加.最好是另外封装,不影响现在的代码.

[百度空间] [note] pointer to member is a POD type的更多相关文章

  1. jquery-plugin-biggerLink,highLight-层加亮_andy 阳光生活_百度空间

    How to get the xpath by clicking an html element How to get the xpath by clicking an html element Qu ...

  2. Android手机无法访问百度空间的解决办法

    本文网址:http://www.cnblogs.com/tunnel213/p/4301165.html 现象: 百度“JavaScript函数高级”后找到一篇文章,百度空间的,无法查看: 配置: 三 ...

  3. document.domain - JavaScript的同源策略问题:错误信息:Permission denied to access property 'document'_eecc00_百度空间

    document.domain - JavaScript的同源策略问题:错误信息:Permission denied to access property 'document'_eecc00_百度空间 ...

  4. memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间

    memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间 memcached vs MySQL Memory engin ...

  5. 提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间

    提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间 提高mysql memory(heap) engine内存性能的开源补丁

  6. sort 使用 tab键 作为 分隔符_人生如梦_百度空间

    sort 使用 tab键 作为 分隔符_人生如梦_百度空间 sort 使用 tab键 作为 分隔符 For some reason "\t" doesn't work right, ...

  7. centos5.5字体为方块问题的解决_深入学习编程_百度空间

    centos5.5字体为方块问题的解决_深入学习编程_百度空间 centos5.5字体为方块问题的解决 一.yum -y install fonts-chinese二.yum -y install f ...

  8. 毕业论文评审意见、导师意见范文、模板_Smile~风_百度空间

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  9. Attribute name invalid for tag form according to TLD异常解决办法_gaigai_百度空间

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

随机推荐

  1. Nginx下10个安全问题提示

    Nginx是当今最流行的Web服务器之一.它为世界上7%的web流量提供服务而且正在以惊人的速度增长.它是个让人惊奇的服务器,我愿意部署它 下面是一个常见安全陷阱和解决方案的列表,它可以辅助来确保你的 ...

  2. javascript回车完美实现tab切换功能

    javascript通过回车实现tab切换功能,最经有一个项目是给化工厂做的在使用的过程中需要输入大量的数据,使用的都是小键盘区,在以前都是通过excel录入数据的现在, 在网页上需要实现excel ...

  3. PHP变量名区分大小写,函数名不区分大小写

    PHP变量名区分大小写,函数名不区分大小写,经常被新手忽视的小细节,测试如下. PHP变量名区分大小写测试: <?php $aaa = "phpddt.com"; $AAA ...

  4. 入门级的PHP验证码

    参考了网上PHP 生成验证码很多是类封装了的,没有封装的验证码其实只是几个GD函数而已,初学者可以看看,可以尝试自己封装. <?php   session_start();      $im = ...

  5. IOS学习2

    1. #import,#include 和@class的区别 都引用一个类,根本定义区别:#include ,#import会把所有的copy一份到该文件 #import比#include的优势,im ...

  6. tcp,第一个例子,客户端,服务端

    1.客户端 package cd.itcast.xieyi; import java.io.IOException; import java.io.OutputStream; import java. ...

  7. ARM时钟初始化

    2440: S3C2440可以使用外部晶振(XTIpll)(默认为12MHZ)和外部时钟(EXTCLK)两种方式输入时钟信号.它由跳线OM[3:2]决定.S3C2440 默认的工作主频为12MHz(晶 ...

  8. python小算法(一)

    1.长度为m的字符串a,长度为n的字符串b,(m>n) 判断b中的字母是否全在a中? O(n)最小. class Num(object): def getNum(self, m): numLis ...

  9. Python-memcached的基本使用

    想学Python,又想研究下memcached的客户端,于是拿Python-memcached研究研究~~~ 1.memcached的安装 请参考本博另一文章<Linux下安装memcached ...

  10. 2. VS使用---HelloWorld

    摘要: ------------------------------------------------------------------------------------- 1. VS2010里 ...