艺术编程

死不惊人死不休

翻译 [翻译] Effective C++, 3rd Edition, Item 43: 了解如何访问 templatized base classes(模板化基类)中的名字(上)收藏

Item 43: 了解如何访问 templatized base classes(模板化基类)中的名字

作者:Scott Meyers

译者:fatalerror99 (iTePub's Nirvana)

发布:http://blog.csdn.net/fatalerror99/

假设我们要写一个应用程序,它可以把消息传送到几个不同的公司去。消息既可以以加密方式也可以以明文(不加密)的方式传送。如果我们有足够的信息在编译期间确定哪个消息将要发送给哪个公司,我们就可以用一个 template-based(模板基)来解决问题:

class CompanyA {
public:
  ...
  void sendCleartext(const std::string& msg);
  void sendEncrypted(const std::string& msg);
  ...
};

class CompanyB {
public:
  ...
  void sendCleartext(const std::string& msg);
  void sendEncrypted(const std::string& msg);
  ...
};
...                                     // classes for other companies

class MsgInfo { ... };                  // class for holding information
                                        // used to create a message
template<typename Company>
class MsgSender {
public:
  ...                                   // ctors, dtor, etc.

  void sendClear(const MsgInfo& info)
  {
    std::string msg;
    create msg from info;

    Company c;
    c.sendCleartext(msg);
  }

  void sendSecret(const MsgInfo& info)   // similar to sendClear, except
  { ... }                                // calls c.sendEncrypted
};

这个能够很好地工作,但是假设我们有时需要在每次发送消息的时候把一些信息记录到日志中。通过一个 derived class(派生类)可以很简单地增加这个功能,下面这个似乎是一个合理的方法:

template<typename Company>
class LoggingMsgSender: public MsgSender<Company> {
public:
  ...                                    // ctors, dtor, etc.
  void sendClearMsg(const MsgInfo& info)
  {
    write "before sending" info to the log;

    sendClear(info);                     // call base class function;
                                         // this code will not compile!
    write "after sending" info to the log;
  }
  ...

};

注意 derived class(派生类)中的 message-sending function(消息发送函数)的名字 (sendClearMsg) 与它的 base class(基类)中的那个(在那里,它被称为 sendClear)不同。这是一个好的设计,因为它避开了 hiding inherited names(隐藏继承来的名字)的问题(参见 Item 33)和重定义一个 inherited non-virtual function(继承来的非虚拟函数)的与生俱来的问题(参见 Item 36)。但是上面的代码不能通过编译,至少在符合标准的编译器上不能。这样的编译器会抱怨 sendClear 不存在。我们可以看见 sendClear 就在 base class(基类)中,但编译器不会到那里去寻找它。我们有必要理解这是为什么。

问题在于当编译器遇到 class template(类模板)LoggingMsgSender 的 definition(定义)时,它们不知道它从哪个 class(类)继承。当然,它是 MsgSender<Company>,但是 Company 是一个 template parameter(模板参数),这个直到更迟一些才能被确定(当 LoggingMsgSender 被实例化的时候)。不知道 Company 是什么,就没有办法知道 class(类)MsgSender<Company> 是什么样子的。特别是,没有办法知道它是否有一个 sendClear function(函数)。

为了使问题具体化,假设我们有一个要求加密通讯的 class(类)CompanyZ

class CompanyZ {                             // this class offers no
public:                                      // sendCleartext function
  ...
  void sendEncrypted(const std::string& msg);
  ...
};

一般的 MsgSender template(模板)不适用于 CompanyZ,因为那个模板提供一个 sendClear function(函数)对于 CompanyZ objects(对象)没有意义。为了纠正这个问题,我们可以创建一个 MsgSender 针对 CompanyZ 的特化版本:

template<>                                 // a total specialization of
class MsgSender<CompanyZ> {                // MsgSender; the same as the
public:                                    // general template, except
  ...                                      // sendCleartext is omitted
  void sendSecret(const MsgInfo& info)
  { ... }
};

注意这个 class definition(类定义)开始处的 "template <>" 语法。它表示这既不是一个 template(模板),也不是一个 standalone class(独立类)。正确的说法是,它是一个用于 template argument(模板参数)为 CompanyZ 时的 MsgSender template(模板)的 specialized version(特化版本)。这以 total template specialization(完全模板特化)闻名:template(模板)MsgSender 针对类型 CompanyZ 被特化,而且这个 specialization(特化)是 total(完全)的——只要 type parameter(类型参数)被定义成了 CompanyZ,就没有剩下能被改变的其它 template's parameters(模板参数)。

(点击此处,接下篇)

发表于 @ 2005年12月07日 19:57:00|评论(loading...)

新一篇: [翻译] Effective C++, 3rd Edition, Item 43: 了解如何访问 templatized base classes(模板化基类)中的名字(下) | 旧一篇: [翻译] Effective C++, 3rd Edition, Item 42: 理解 typename 的两个含义

用户操作
[即时聊天] [发私信] [加为好友]
fatalerror
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
fatalerror的公告
Copyleft © 2005 - 2009 by fatalerror99 (iTePub's Nirvana)

本 BLog 所有文章除注明转载者外,均为本人原创或翻译,欢迎转载。转载时请保持文章完整并注明出处。

强烈推荐使用 Mozilla Firefox 浏览本 BLog。

MSN: fatalerror9999@hotmail.com

e-mail: fatalerror99@gmail.com

文章分类
收藏
    My baby
    我家未未(RSS)
    Our Projects
    boost 文档汉化 boost_doc_translation(RSS)
    不服不行
    Bjarne Stroustrup
    Alexander A. Stepanov
    Andrei Alexandrescu
    Bruce Eckel
    Charles Petzold
    Chris Sells
    David R. Musser
    Dennis M. Ritchie
    Donald E. Knuth
    Herb Sutter
    James Gosling
    Nicolai M. Josuttis
    Scott Meyers
    Stanley B. Lippman
    侯捷
    荣耀
    精点 BLog
    水瓶水蓝
    水瓶水蓝 —— 晃荡在阴阳两界的魂儿
    (RSS)
    CityLife 的流水账(RSS)
    为艺术而技术(RSS)
    乱发当风(RSS)
    微起涟漪 —— basse(RSS)
    暗金色月亮的赫拉迪克宝盒(RSS)
    杏坛雨的博客(RSS)
    王晓渔:书中自有……(RSS)
    开发 BLog
    C++ 的罗浮宫(RSS)
    Coofucoo's Blog--The Unadulterated Coofucoo(RSS)
    GreenCode's Blog(RSS)
    ilovevc 的专栏(RSS)
    Jeffrey Richter's Blog(RSS)
    lxwde 的专栏(RSS)
    oiramario(RSS)
    Ralph Zhang --- 在这里我只谈技术(RSS)
    ralph623 的专栏(RSS)
    renco 的专栏(RSS)
    Scorpio Auding @ Blog++(RSS)
    SnowFalcon 的专栏(RSS)
    Stan Lippman's BLog(RSS)
    Sutter's (Online) Mill(RSS)
    切尔斯基(RSS)
    刘未鹏 Mind Hacks
    周星星 之 Blog(RSS)
    孟岩(RSS)
    开心就好的代码人生(RSS)
    心如止水 —— coofucoo 的专栏(RSS)
    方舟(RSS)
    歌谣在风中飘舞(RSS)
    相信开源的力量(RSS)
    空谷幽兰,心如皓月 —— 陈皓专栏(RSS)
    艺术编程(RSS)
    透明思考 - 1(RSS)
    透明思考 - 2(RSS)
    陈硕的 Blog(RSS)
    开发网站
    CSDN.NET
    artima devdloper: Best practices in enterprise software development
    Experts Exchange
    IBM DeveloperWorks
    IBM DeveloperWorks 中国(RSS)
    Programmers' Heaven
    The Artima Developer Community
    The Code Project
    卡卡社区
    开发语言与环境
    (CHEZ (CHEZ SCHEME))
    .NET Languages
    PHP: Hypertext Preprocessor
    Eclipse.org home
    Python Programming Language
    REBOL Technologies
    ActiveState
    D Programming Language
    Eclipse Plugins
    Eclipse Plusin Central
    Eiffel Software
    GCL - GNU Common Lisp
    GNU Compiler Collection (GCC)
    Groovy
    IronPython
    NetBeans IDE
    Perl
    Ruby on Rails
    Ruby Programming Language
    The Programming Language Lua
    坛子若干
    iTePub
    自由小店 —— iTePub 共建共享电子图书交互平台
    (RSS)
    ChinaJavaWorld.com 技术论坛
    ChinaUnix
    CSDN 技术社区 —— 这个不说大家也知道
    Huihoo - Open Source Community
    ITPUB 论坛
    卡卡社区
    网络书店
    Amazon.com
    China-Pub 网上书店
    joyo Amazon 卓越亚马逊
    第二书店
    有一杯咖啡叫做 Java
    Hibernate
    Java Technology
    JavaWorld
    jGuru
    Spring Framework
    The Apache Software Foundation
    TheServerSide.COM: Your Enterprise Java Community
    有一部经典叫做 C++
    Boost C++ Libraries
    C Programming and C++ Programming
    C/C++ Reference
    cplusplus.com
    Programming in C++, Rules and Recommendations
    The ADAPTIVE Communication Enviroment (ACE)
    The C Standards Committee (ISO C)
    The C++ Standard Committee (ISO C++)
    有一只企鹅叫做 Linux
    Debian
    Fedora Project
    Linux Journal
    Linux Online!
    Linux 伊甸园
    Linux.com
    Red Hat
    SUSE Linux Enterprise from Novell
    The Linux Foundation
    The Linux Kernel Archives
    Ubuntu
    有一种自由叫做开源
    OpenBSD
    CodeGuru
    FreeBSD
    FSF - The Free Software Foundation
    GNU
    Huihoo - Open Source Community
    Open Source Initiative (OSI)
    OpenSolaris
    SourceForge.net
    The Open Enterprise Foundation (OEF)
    专业出版机构
    Addison-Wesley
    APress
    Manning Publications Co.
    McGraw-Hill
    O'Reilly
    Prentice Hall PTR
    Wiley
    Wordware Publishing, Inc.
    Wrox
    存档
    软件项目交易
    Csdn Blog version 3.1a
    Copyright © fatalerror