模版

作者: 呼吸秋千_6e9c | 来源:发表于2019-04-14 23:45 被阅读0次

1.1 实验内容
本节内容主要讲述 c++11 模板的用法,以后的代码中会大量的用到模板的知识。同时简单讲解迭代器的相关知识,为后面容器和算法的内容作铺垫。

1.2 实验知识点
模板编程
-基本语法
-模板函数
-类模板和成员模板
-模板类中的静态成员
-typename和class
迭代器
-迭代器详解
-迭代器种类和使用

模板的基本语法如下:

template <typename/class T>

template 告诉编译器,接下来是一个模板 ,typenameclass 都是关键字,在这里二者可以互用没有区别。在< >中 T 叫做模板形参,一旦模板被实例化,T 也会变成具体的类型。接下来,我们看一个例子。

模版函数

代码实例:

 template <typename T>
 T  add(const T lva ,const T rva) 
 {

     T a ;

     a = lva + rva ;

    return a;    
 }

这是一个模板函数的简单实例,所有模板函数在开始都需要 template 语句,以告诉编译器这是一个模板和参数等必要信息,当然里面的 T 可以取任意你喜欢的名字 ,模板参数个数也是任意更换的。 还要提醒的一点是:template <typename T1 ,typename T2 = int>函数模板是支持默认参数的,T1 、T2顺序在默认情况下是可以任意的,不用严格按照从右到左的顺序。

然后就是使用了,我们可以写出add(1,2) 这样的函数,也可以写出add(2.5,4.6)这样的函数,向 add 函数提供参数时,编译器会自动分析参数的类型,然后将所有用到 T 定义的换成相对性的类型,以上的两个函数在编译期间会生成

 int add(const int lva ,const int rva) 
{

     int a ;

     a = lva + rva ;

    return a;    
 }
 double add(const double lva ,const double rva) 
 {

     double a ;

      a = lva + rva ;

    return a;    
 }

这样的两个具体函数。如果我们使用add(1,2.0)是会报错的,编译器无法找到add(int,double)。大家可以自己分析一下为什么。

类模版

c++11 不仅支持对函数的模板化,也支持对类的模板,下面来看基本的语法是怎样的:

 template <class T>
 class Myclass
 {
     T a;
     public:
         T add(const T lva ,const T rva);
 };

 template <class T>
 T Myclass<T>::add(const T lva, const T rva)
 {
     a = lva + rva;
     return a;
 }

这是一个简单并且典型的类模板,在程序中给出模板并不能使用它,还必须实例化,比如:

Myclass<int> A; //用 int 实例化一个类A

Myclass<double> B; //用 double 实例化一个类B

当程序编译到这里时就会按照我们给出的类型,声明两组类和两组类函数。注意,在这里我们一定要显式给出类型 T 。类模板不像是函数模板 ,函数模板会根据参数推断类型。 当然类模板也支持默认参数,但是类模板必须严格从右往左默认化。

成员模板

模板的使用范围是广泛的,不仅可以用作函数模板,类模板,还可以用作 class ,struct ,template class 的成员。而要实现 STL 这是我们必须掌握和使用的特性。我们先看一个简单的例子,用上面的类改编而来:

 template <class T>
 class Myclass
 {
     public:
        T a;
        template <typename type_1 , typename type_2>
         type_1 add(const type_1 lva ,const type_2 rva);
 };

 template <class T>
     template <typename type_1,typename type_2>
 type_1 Myclass<T>::add(const type_1 lva, const type_2 rva)
 {
     a = lva + rva;
     return a;
 }

在类的声明中使用了一个嵌套的模板声明。且通过作用域运算符 :: 指出 add 是类的成员,需要注意的一点,有些编译器不支持模板成员,而有些编译器不支持在类外定义。我们默认大家的编译器都支持。模板如此强大,甚至允许我们在模板类中再建立模板类:

 template <class T>
 class Myclass
 {
     public:
        T a;
        template <typename type_1 , typename type_2>
         type_1 add(const type_1 lva ,const type_2 rva);

         template <class type_3>
         class Myclass_2;         // 声明放在这里,具体定义放在类外进行。
         Myclass_2<T> C;          // 定义一个Myclass_2 类 A。使用 T 进行实例化
 };

 template <class T>
     template <typename type_1,typename type_2>
 type_1 Myclass<T>::add(const type_1 lva, const type_2 rva)
 {
     a = lva + rva;
     return a;
 }

 template <class T>
     template <class type_3>
     class Myclass<T>::Myclass_2
     {
         public:
             type_3 value;
             type_3 sub(const type_3 a , const type_3 b) {vlaue = a - b;} 
     };

当然我们暂时还用不到这样复杂的东西,这里只是展现了模板的部分特性。

我们知道,在类中定义的静态成员是存储在静态区中,被所有类对象共享,并不属于某一个类所有,同样的在模板类中的静态成员也不会被复制多份,而是被同类实例化的类对象共享,比如所有 int 和所有 double 的类对象,享有相互独立的静态变量。也可以说是编译器生成了 int 和 double 两个版本的类定义。

typename && class

typenameclass是模板中经常使用的两个关键词 ,在模板定义的时候没有什么区别。以前用的是 class,后来 c++ 委员会加入了 typename。因为历史原因,两个是可以通用的。对有些程序员来说,在定义类模板的时候,常常使用 class 作为关键字,增加代码可读性。其它则用 typename,上面的代码大都遵循这样的标准,但是并无强制规定。但是如果二者没有差别,为什么还要加入typename呢?c++标准委员会不会增加无用的特性,让我们来看一个例子:

class Myclass{
    public:
        Myclass();
        typedef int test;  //定义类型别名
}
template <class T>
class Myclass2{
    public:
        Myclass2();
        T::test *a  // 声明一个指向T::test类型的指针。
        //   typename T::test * a
}

以上的代码没有全部写完,大家觉得编译器能够过吗?答案是不能,因为在 c++ 中,允许我们在类中定义一个类型别名,且使用的时候和类名访问类成员的方法一样。这样编译器在编译的时候就会产生二义性,它根本不知道这是一个类型还是别名,所以我们加上 typename 显式说明出来。当然如果这里没有二义性,比如Myclass ::test * a ,加上 typename 是会报错的。此外,在 class 的 STL 底层还有一个特性,用于保留模板参数,但是在 c++17 中已经舍弃,所以我们没有讲。

[](javascript:;)

相关文章

  • 10.1KOA ejs 模版引擎

    ejs 模版引擎 安装模版引擎中间件 安装模版引擎 定义模版 使用模版引擎 具体 ejs 模版引擎使用 http:...

  • 10.2KOA handlebars 模版引擎

    handlebars 模版引擎 安装模版引擎中间件 安装模版引擎 定义模版文件 使用模版引擎 具体 handleb...

  • 三十二:Django之模版使用

    一:创建模版文件夹 二:配置模版目录 三:使用模版文件 四:给模版文件传递数据 模版变量使用:{{ 模版变量名 }...

  • day06-模版使用

    1)创建模版文件夹2)配置模版目录 3)使用模版文件 给模版文件传递数据模版变量的使用{{ 模版变量名 }}ind...

  • 模版

    模版 模版函数 使用模版函数不需要指定类型,直接传参就可以了。 模版类 使用模版类需要指定类型。

  • IDEA-注释模版设置

    设置注释模版,比如userDefine 设置Java类注释模版 *c 设置Java方法注释模版 * 选择模版范围i...

  • Python_Flask 基础2

    1模版语法 1.1 模版语法主要分为两种: 变量和标签 模版中的变量 : {{ var }} 模版中的标签:{% ...

  • 后台模版框架样式

    整体模版使用Miminium的模版 注:Miminium模版是github上一款开源后台模版 整体构思 左侧菜单栏...

  • Django 框架之 自定义标签

    知识点 模版是一个用django模版语言标记过的python字符串。模版可以包含模版标签和变量。 模版标签是在一个...

  • 总结2015:10个最佳响应式网站设计模版

    微相册展示模版 适合做分类信息展示的模版,博客模版 最佳博客模版 最佳企业宣传网页模版,多终端适配,适用于营销型企...

网友评论

      本文标题:模版

      本文链接:https://www.haomeiwen.com/subject/vrbrwqtx.html