正在阅读:C++语言风格流变史C++语言风格流变史

2005-05-19 15:11 出处: 作者:王咏刚 责任编辑:xietaoming

5. ATL——COM时代的另类C++

    除了STL模板库之外,还有一个与模板风格相关的例子。下面的代码片断取自Visual C++自动生成的ATL控件工程:

class ATL_NO_VTABLE CMyATLObj :
    public IMyATLObj,
    public IpersistStreamInitImpl
        <CMyATLObj>,
    public IOleControlImpl<CMyATLObj>,
    public IOleObjectImpl<CMyATLObj>,
    public IoleInPlaceActiveObjectImpl
        <CMyATLObj>,
    public IViewObjectExImpl<CMyATLObj>,
    public IoleInPlaceObjectWindowlessImpl
        <CMyATLObj>,
    public IPersistStorageImpl<CMyATLObj>,
    public IspecifyPropertyPagesImpl
        <CMyATLObj>,
    public IQuickActivateImpl<CMyATLObj>,
    public IDataObjectImpl<CMyATLObj>,
    public IProvideClassInfo2Impl
        <&__uuidof(CMyATLObj), NULL>,
    public CComControl<CMyATLObj>
......

    注意控件类CMyATLObj的代码,CMyATLObj类居然是从N个接口类和控件类中派生出来的,类的声明语句中随处可见模板的身影——这就是Microsoft为我们设计的别具一格的ATL风格的代码了。之所以要不惜代价地大量使用模板、多重继承等语言特性,这主要为了适应COM、OLE、ActiveX等在架构上本来就相对复杂的技术体系。但这样一来,使用ATL的代码在所有C++代码中,就拥有了一副异乎寻常的长相了:到处都是尖括号,到处都是以“I”打头的标识符,甚至还有多重尖括号的嵌套……如果要求一个刚学会C++语言的程序员立刻读懂一大段ATL代码,我想,用不了几分钟,他就会被代码中那些晦涩、离奇的语言风格折磨得精神崩溃了。

6. 标准C++——一种全新的语言?

    C++语言的标准化进程远远落后于语言本身的普及速度。1990年以后,ANSI/ISO的C++标准化委员会才将包括Stroustrup在内的大批专家以及包括Apple、Borland、DEC、HP、IBM、Microsoft、Sun、Unisys在内的知名公司召集在一起,像所有国家的议会或人民代表大会一样通过没完没了的会议、讨论和投票制定C++的国际标准。标准直到1998年9月才正式发布。在国际标准化组织的档案库里,C++标准的代号是ISO/IEC 14882:1998。

    Stroustrup建议我们把标准C++当作一种全新的语言来学习[3]。这一说法显然是基于这样一个事实:标准C++语言已经拥有了一种稳定的、可以推广的语言风格,即,通过对STL等既有技术的肯定,ANSI/ISO委员会在1998年的标准中正式认可了包括模板、容器类、I/O流库、异常处理等典型语言特征的现代C++风格。风格的稳定意味着语言本身的进步和成熟,也意味着程序员们对C++的认识必须上升到一个新的层次——那些至今还在编写仅由类和C语言库函数组成的C++代码的程序员,一定会成为Stroustrup及其同仁们的取笑对象的。

    Stroustrup的《C++程序设计语言》第3版对标准C++风格做了最权威的阐释。在Stroustrup等专家学者的号召下,越来越多的项目开始编写符合标准C++风格的代码。这一点在许多开放源代码的项目中体现得特别明显。这多半是由于,使用C++语言的开源项目大多都不会像大企业里的项目组那样,在语言风格上会受到公司背景或历史习惯的羁绊。在具体的编程实践中,开源项目的程序员们一方面可以坚决地贯彻标准C++的语言风格,另一方面也可以根据自己的喜好为代码增添一些感情色彩。例如,在OpenOffice的源码中,标识符的前缀规范就相当有特点,连指针和引用类型的变量都由不同的前缀字母区分;下面给出的Linux桌面管理器KDE 3.1.4的源代码片断则显示出,开发KDE的程序员在代码风格上或多或少受到了Java语言风格的影响:

class delUser: public KDialogBase {
  Q_OBJECT
public:
  delUser(KUser *AUser, QWidget *parent = 0,
     const char *name = 0);
  bool getDeleteHomeDir()
     { return m_deleteHomeDir->isChecked(); }
  bool getDeleteMailBox()
     { return m_deleteMailBox->isChecked(); }
private:
  QCheckBox *m_deleteHomeDir;
  QCheckBox *m_deleteMailBox;
};

键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品