随笔-14  评论-8  文章-0  trackbacks-0

      记得在看《windows 核心编程》第二十五章的 Spreadsheet 示例程序时,我对其中 typedef 的用法很是困惑。当时翻看了《Big c++》(我的第一本 c++ 书籍),很可惜,上面讲得很简单,不足以解答我的疑惑。不知为什么当时没有坚持去解决那个问题,一直到现在才想起来对 typedef 做个全面的回顾。STL 和 BOOST 为我们呈现了众多精彩的应用,typedef 功不可没。先看看 《c++ primer》 怎么说的:

      Introduces a synonym for some other type. Form:

      为某种类型引入同义词。格式:

      typedef type synonym;
     

      defines synonym as another name for the type named type.

      定义 synonym 为名为 type 的类型的另一名字。

      在看《核》一书的时候,我的了解就这么一点。为什么我看不懂呢?看看《核》中的用法:

const int g_nNumRows = 256;
const int g_nNumCols = 1024;

typedef struct {
    DWORD dwValue;
    BYTE  bDummy[1020];
} CELL, *PCELL;

typedef CELL SPREADSHEET[g_nNumRows][g_nNumCols];
typedef SPREADSHEET *PSPREADSHEET;
    按照当时的想法,句子 SPREADSHEET[g_nNumRows][g_nNumCols] sh 的意思应该是 CELL sh ,不就该是这样的吗(因为它只是个别名/马甲)?但在我那个想法里 sh 可不是数组,所以我当时无法理解 sh 后来的行为。形式主义,对,形式主义影响了我,当时我就一彻底的形式主义者。我还想再一遍地重复这个词,不过那也太给它面子了。算了, Not worth to fight!(哈,最近看的一部精彩的家庭喜剧中的台词。这部剧名叫《the middle》)。《核》一书中接下来还有一个精彩的用法,为了简化代码,我把它写成这个样子:
class Base {
public:
    virtual ~Base();
    void fn();
    ...
private:
    int n;
};

class Derive : public Base {
    ...
    //no data member allow, just function here.
};
static Derive g_ssObject;
SPREADSHEET& g_ss = *(PSPREADSHEET)(PCELL)g_ssObject;
    如此一来,g_ss 就有了 Base 的 n 成员和 256 * 1024 个 CELL 结构。当向 Derive 对象使用 [] 时(它是 SPREADSHEET& 型),它的行为就跟数组一致了(n 成员不会索引到,这也是不允许派生类有数据成员的原因)。关于它的内存并没有在它声明的时候开辟,以及后来怎么开辟,那就是另一个冒险故事了。这种手法让我再一次为《核》这本书所折服。
    好了,回到 typedef 。我见得最多的用法不外乎 typedef int value_type ,“取绰号”是他的职责所在,我不能只把它理解为:当你看到 B( value_type ) 时,它只不过是 A ( int ),还要把它理解为像上面提到的一样:SPREADSHEET 并不只是一个 CELL ,而是多个 CELL 组成的 Array 的首个元素的位置指针,不然后面的两个跟屁虫双胞胎 “[][]” 作何解释。我的这种想法让我想起了 ATL 中的 OLECHAR ,在那里我也曾是个形式主义者(又重复了一遍!)。OLECHAR 在特定的平台上有特定的意义,比如在 windows 平台并定义了 UNICODE 的情况下,它是 wchar_t 。如果保持这种理解,将无法把它当做一种特别的类型,从而在语言层面上有了障碍,也就违背了 OLECHAR 生来是为 COM 组件做“特殊”服务的本意。我们要把它当做基本类型看待,至于怎么看待以及详细的方法,另一个冒险故事…… 所以,“取绰号”专家的内涵并不单薄,我不能一厢情愿的认为他只是个爱捉弄人的讨厌鬼,它正经起来可也是一表人才滴。下面是一些 typedef 的用法(来自《c++模板元编程》中某习题的解答):
class foo {...};

typedef int (foo::*pmd);    // pmd 解释为:指向 foo 数据成员的指针,返回值为 int
typedef int (foo::*pmf)();  // pmf 解释为:指向 foo 函数成员的指针,返回值为 int
typedef int (*pfunc)();     // pfunc 解释为:指向函数的指针,返回值为 int 且无参数(有参数的也就不难想象了)
typedef const int& refc;    // 不说这个了
    上面的展示非常不全面,网上总结的东西一大堆,我不能偷懒引用,去看才实在。不过有了这些知识,理解其它东西应该足够了。
posted on 2009-12-09 21:20 崇文 阅读(461) 评论(0)  编辑 收藏 引用

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