Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1039544
  • 博文数量: 243
  • 博客积分: 3053
  • 博客等级: 中校
  • 技术积分: 2975
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-02 21:11
文章分类

全部博文(243)

文章存档

2013年(2)

2012年(20)

2011年(5)

2010年(114)

2009年(102)

我的朋友

分类: C/C++

2009-06-04 10:16:36

  // TemplateBug.cpp : 定义控制台应用程序的入口点
  //
  #include "stdafx.h"
  
  // 先定义一个接口
  template < class DataType >
  class A
  {
  public:
   virtual int SomeFunc(const DataType &Value ) = 0;
  };
  
  // B来实现这个接口为这样,竟然编译不过!
  template< class something1, class something2 >
  class B : public A< char* >
  {
  public:
   virtual int SomeFunc( const char* &Value ) { return 0; };
  };
  
  // 改成这样编译才能通过
  template< class something1, class something2 >
  class C : public A < char* >
  {
  public:
   virtual int SomeFunc( char* const &Value ) { return 0; };
  };
  
  // const char* 和 char* const 的含义是大不一样的,可是经过模板的参数化过程
  // 后,混淆了两者,这应该算个BUG了吧?
  
  int _tmain(int argc, _TCHAR* argv[])
  {
   B< int, int > b; // 注释此行后编译通过
   C< int, int > c;
   return 0;
  }
  其中那段注释很有意思,但是这个不是bug,相反,应该说这样才是符合C++规范的,
  不是编译器混淆了两者,而是我们的作者混淆了两者。
  再来看const char* &p 和 char* const &p 两种引用:
  两者都是对一个对象的引用。
  但是前者的“这个对象”是 const char*,一个指向 const char 的指针,注意!虽
  然这个指针指向的char不可以改变,但这个指针本身的值是可以改变的,也就是说,
  他可以被改变而指向另一个 const char 对象。
  后者的“这个对象”则是char*, 一个指向char的指针。这个指针指向的东西是可以
  改变的,但是这个指针本身是不能改变的,你不能让他指向另一个char对象。
  如果你觉着这段表述不够清晰,请自行编译一下下面这段代码:
  void fconst( const char* & p ) {
   *p = 'L'; // error C2166: l 值指定常数对象
   p ++; // OK!
  }
  void constf( char* const & p ) {
   *p = 'L'; // OK!
   p ++ ; // error C2166: l 值指定常数对象
  }
  int main () {
   char str[] = "Hello world";
   char* p = &str[2];
   fconst(p);
   constf(p);
  }
  现在const char *& 与 char* const& 的区别已经清楚了,那么我们看模板如何特化的
  作者的SomeFunc的参数是一个DataType的const reference,所谓的const reference,
  是说你不能再改变这个reference所引用的对象的状态,因此 const DataType & 和
  DataType const &是等价的,也就是说, template A 的函数SomeFunc
  的参数是一个对某个对象的常引用,这个引用所引用的对象的状态在函数作用域内不
  可以被改变。
  那么很明确吧,A< char* > 被特化作为 class B 和 C 的基类,那么它的纯虚成员函数
  SomeFunc的参数就被特化为对于char* 的const reference了,SomeFunc也就具有形式
  int SomeFunc( char* const& ),因此如果定义成int SomeFunc(const char* &Value)
  不会与纯虚函数匹配,自然变成的普通的虚函数,而纯虚函数没有定义:
  error C2259: “B” : 不能实例化抽象类
   with
   [
   something1=int,
   something2=int
   ]
   由于下列成员:
   “int A::SomeFunc(const DataType & )” : 未定义纯虚函数
   with
   [
   DataType=char *
   ]
   tempBUG.cpp(5) : 参见“A::SomeFunc”的声明
   with
   [
   DataType=char *
   ]
阅读(5210) | 评论(0) | 转发(0) |
0

上一篇:J2EE的OA项目(2)

下一篇:XML文档定义

给主人留下些什么吧!~~