Note of Justin

关于工作和读书的笔记

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

留言簿(14)

搜索

  •  

积分与排名

  • 积分 - 51743
  • 排名 - 433

最新评论

阅读排行榜

评论排行榜

[原创文章欢迎转载,但请保留作者信息]
Justin  于 2010-03-04

话说看书看到第七章,大师开始讲模板。

41 课首先要讲的是:面向对象 (OO) 编程强调的是具体的接口和运行时的多态;而模板编程恰恰相反,侧重于模糊的接口以及编译期的多态。

具体的接口 (explicit interface) 有着具体的类型 ( 包括参数的,内部变量的,返回值的等等 ) ,这些类型被大师称为接口的特征 (signature) ;而模糊的接口却没有这些限制,取而代之的是表达式 (expression)

运行时的多态由虚拟机制而生,对象的运行时类型决定了真正得到执行的函数 / 接口 / 方法是什么;这和编译期的多态有些类似,不过后者多态特性是在程序编译期间呈现的:不同的模板参数决定了不同的函数会被调用。

例子就不举了,如果不清楚什么是模板,那么最好 Google 一下,会有一堆的入门读物。(哦对了,不知道现在Google是否会需要翻墙……)


OK ,下一课吧。

42 课的中心思想是 typename 的两重意义。
下面的课前作业做了没?

template <class T> class TClass1;
template 
<typename T> class TClass2;

TClass1 TClass2 有什么区别?

答案是没有区别。因为当定义模板参数时,用 class typename 是没有差异的。

既然用了两个不同的名字,自然会有不一样的地方。
下面便是一处应该用
typename 而不能用 class 的情形:

由于模板的中接口的模糊性质,下面的函数模板便有了这样那样的问题:

见下面的程序片段:T::name 的本意可能是模板 T 所指代的类中的 name 类型,而 pName 就是指向这种类型对象的指针。
但是模板中的接口是模糊的,所以同样的模板会因为 T 的不同而产出不一样的实际代码。如果 T :: name 不是一个类型,而是 T 的一个成员,然后如果人品真的很差, pName 是一个全局变量,这一句就变成了将 T::name pName 相乘! ( 看到这里不得不佩服大师举例子的能力,这样都想得到 ……)
template <typename T>
void TFunc()
{
   T::name 
* pName; // this won't even compile
  
// and it should be
  
// typename T::name * pName;
  
//..
}
会发生这种惨案的原因是因为 C++ 在这种情形下,如果没有显式声明,就默认 T::name 不是个类型。于是这个时候就需要 typename 来显式地告诉编译器这个其实是个类型而非其他东东。当然,在这里 class 是无法替代 typename 的作用的。

书中把上面的情况用语法来描述: typename 必须放在前面修饰 嵌套从属类型名 ”(nested dependent type name)
个人觉得太拗口难记,所以还是记着上面的例子好了。

不过这个规定也还是有个例外,那就是 typename 作用于 嵌套从属类型名 时不能用于 (1) 基类列表,以及 (2) 成员初始化列表中。如下所示
template <typename T>
class TClass():public BClass<T>::NestedClass
//             ----------------------> (1)no typename is needed, nor allowed
{
   
explicit TClass(int x) : BClass<T>::NestedClass(x)
//                          -------------------------> (2)no typename is needed, nor allowed
   {
      
//..
   }
   
//..
};
如果觉得这种用法会打很多字 (@# %) 可以用 typedef 来减少一点工作量,改写后的例子是这样的:
template <typename T>
void TFunc()
{
   typedef typename T::name 
* pTname;
   
//ok, now we can do this:
   pTname pname1;
   pTname pname2;
//..
}
posted on 2010-03-23 13:05 Justin.H 阅读(348) 评论(1)  编辑 收藏 引用 所属分类: Effective C++ 炒冷饭

Feedback

# re: 读书笔记:Effective C++ 炒冷饭 - Item 41&42 模板概念若干 2010-05-03 15:15 谢华
写的不错。  回复  更多评论
  


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