读书笔记--模板(2)

来源:互联网 发布:西方经济学教材知乎 编辑:程序博客网 时间:2024/05/16 02:25

模板的编译模型:
  应该将类定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中。要进行模板的实例化,便一起必须能访问定义模板的源代码。
  1、包含编译模型
//utlities.h
#ifndef UTLITIES_H
#define UTLITIES_H

template<class T> int compare(const T&,const T&);
#include "utilites.c"
#endif   //end of utlities.h

//utlities.c
#include "utlities.h"

template<class T>int compare(const T&v1,const T&v2)
{
 if( v1<v2 )
 {
  return -1;
 }
 if( v2<v1 )
 {
  return 1;
 }
 return 0;
}         
//other definetions

这种策略使我们能够保证头文件和实现文件的分离,也保证了编译时使用模板代码能看到两种文件.

  2、分别编译模型
可以使用export关键字让便一起知道要记住给定的模板定义。
export能够指明给定的定义可能会需要在其他文件中产生实例化,一个模板只能定义为导出一次,且不能在模板声明中出现export

export template<typename Type>
Type Sum(Type t1,Type t2)
如果头文件中的类定义体使用了export,则该头文件只能被程序中的一个源文件使用
//class template header goes in shared header file
template<class Type> class Queue{//...};
//Queue.c   implementation file declared Queue as export
export template<class Type> class Queue;
#include "Queue.h"
导出类的成员将自动声明为导出,也可以将类模板的个别成员声明为导出的


非类型形参的模板实参:
template<int i,int wid>
class Screen
{
 public:
  Screen():Screen(hi*wid,'#'),cursor(0),height(hi),width(wid){}
 private:
  string screen;
  string::size_type cursor;
  string::size_type height,width;
};

该模板有两个非类型形参,使用Screen类型时序显示声明为Screen<24,80>
非类型模板实参必须是编译时常量表达式


类模板的友元声明:
template<class Type>class Bar
{
 friend class FooBar;
 friend void fun();    //非模板类或模板函数为类模板的友元
 template<class T>friend class Foo1;
 template<class T>friend void temp_fcn1(const T&);
 //友元可以是类模板或函数模板
};
类也可以只授予对特定实例的访问权
template<class T>class Foo2;
template<class T>void temp_fcn2(const T&);
tempalte<class Type>class Bar;
{
 friend class foo2<char *>;
 friend class temp_fcn2<char *>(char *const &);
 friend class Foo2<Type>;
 friend class temp_fcn2<Type>(const Type &);
};
Foo2是类模板,由原关系只扩充到Foo2的形参类型为char *的特定实例。只有与给定Bar实例有相同模板实参的那些Foo2或temp_fcn版本是友元,因此Foo3<int>可以访问Bar<int>的私有部分,但不能访问Bar<string>或者任意其他Bar实例的私有部分

如果友元类是普通类(不是模板类)则可以不事先声明,反之就需要声明
template<class T>class A;
template<class T>
class B
{
 public:
  friend class A<T>;    //ok,A is known to be a template
  friend class C;       //ok,C must be an ordinary nontempalte class
  template <class S> friend class D;   //ok,D is a template
  friend class E<T>;    //error,E wasn't declared as a template
};

 

 

 

 

 

 

 


 

原创粉丝点击