zoukankan      html  css  js  c++  java
  • 3.0 C++远征:模板

    模板

    三、模板

    1.为什么要引入模板?

    使用模板的目的就是能够让程序员编写与类型无关的代码。

    2.关键字:

    template typename class

    3.函数模板的格式:

    template <class 形参名, class 形参名, ...> 返回类型 函数名(参数列表)
      {
        // 函数体
      }
    

    1.函数模板

    template

    // max.cpp
    template <class T>	// 参数T表明是一种类型
    T max(T a, T b) {	// 函数模板
      return (a > b) ? a : b;
    }
    
    // main.cpp
    // 只写函数模板,不写模板函数,系统是不会产生任何代码数据的
    int main() {
      int iVal = max(100, 99);// 模板函数,无尖括号,默认类型为int
      char cVal = max<char>('A', 'B');// 模板函数,有尖括号<char>,指定类型
          
      return 0;
    }
    

    typename

    // swap.cpp
    // 通过typename定义模板
    template <typename T>
    void swap(T& a, T& b) {
      T tmp = a;
      a = b;
      b = tmp;
    }
    
    // main.cpp
    int main() {
      int x = 20;
      int y = 30;
      swap<int>(x, y);
      
      return 0;
    }
    

    变量作为模板参数

    // display.cpp
    // 变量作为模板的参数
    template <int size>
    void display() {
      cout << size << endl;
    }
    
    // main.cpp
    int main() {
      display<10>();	// 模板参数需传入一个确定的值
      
      return 0;
    }
    

    多参数函数模板

    // display.cpp
    // 多参函数模板
    template <typename T, typename P>
    void display(T a, P b) {
      cout << a << "," << b << endl;
    }
    
    // main.cpp
    int main() {
      int a = 1024;
      string str = "Hello, world!";
      display<int, string>(a, str);	// 使用的时候两个参数的类型都要指定出来
      
      return 0;
    }
    

    typename和class混用

    // minus.cpp
    // 分清模板的参数和函数的参数,二者没有关系
    template <typename T, class C>
    T minus(T* a, U b);
    
    // display.cpp
    template <typename T, int size>
    void display(T a) {
      for(int i = 0; i < size; i++)
        cout << a <<endl;
    }
    
    // main.cpp
    int main() {
      display<int, 5>(15);
      
      return 0;
    }
    

    函数模板与重载

    // display.cpp
    // 三个不同的模板函数之间形成了重载
    template <typename T>
    void display(T a);
    
    template <typename T>
    void display(T a, T b);
    
    template <typename T, int size>
    void display(T a);
    
    // main.cpp
    int main() {
      display<int>(10);
      display<int>(10, 20);
      display<int, 5>(30);
    }
    

    2.类模板

    // MyArray.cpp
    template <class T>
    class MyArray {
      public:
      	void display() {	//在类内定义成员函数
          ...
      	}
      private:
      	T *m_pArr;
    };
    
    // 在类外定义成员函数
    template <class T>
    void MyArray<T>::display() {
      ...
    }
    
    // main.cpp
    int main() {
      MyArray<int> arr;	// 此时产生模板类
      arr.display();
      
      return 0;
    }
    

    多参数类模板

    // Container.cpp
    template <typename T, int iSize>
    class Container {
      public:
      	void display();	// 类内定义成员函数
      private:
      	T m_obj;
    };
    
    // 类外定义成员函数
    template <typename T, int iSize>
    void Container<T, iSize>::display() {
      for(int i = 0; i < iSize, i++)
        cout << m_obj << endl;
    }
    
    // main.cpp
    int main() {
      Container<int, 10> ctn;	// 此时产生模板类
      ctn.display();
      
      return 0;
    }
    

    特别提醒:模板代码不能分离编译

    • 即声明和定义都必须写在.hpp文件中。

    3.标准模板库

    vector:向量

    vector 常用函数
    empty() 判断向量是否为空
    begin() 返回向量迭代器首元素
    end() 返回向量迭代器末元素的下一个元素
    clear() 清空向量
    front() 第一个数据
    back() 最后一个数据
    size() 获得向量中数据
    push_back(elem) 将数据插入向量尾
    pop_back() 删除向量尾部
    ...... ......
    // main.cpp
    int main() {
      vector<int> iVec;
      iVec.push_back(10);
      iVec.push_pop();
      cout << iVec.size() << endl;
      
      return 0;
    }
    

    迭代器:iterator

    • 是一个类
    // main.cpp
    int main() {
      vector vec;
      vec.push_back("hello");
      vector<string>::iterator cIter = vec.begin();
      for(; cIter != vec.end(); cIter++)
        cout << *cIter << endl;
      
      return 0;
    }
    

    list:链表

    map:映射

    map<int, string> m;
    
    pair<int, string> p1(10, "shanghai");
    pair<int, string> p2(20, "beijing");
    
    m.insert(p1);
    m.insert(p2);
    
    cout << m[10] << endl;
    cout << m[20] << endl;
    
    map<string, string> m;
    
    pair<string, string> p1("S", "shanghai");
    pair<string, string> p2("B", "beijing");
    
    m.insert(p1);
    m.insert(p2);
    
    cout << m["S"] << endl;
    cout << m["B"] << endl;
    
  • 相关阅读:
    iOS resign code with App Store profile and post to AppStore
    HTTPS科普扫盲帖 对称加密 非对称加密
    appid 评价
    使用Carthage安装第三方Swift库
    AngularJS:何时应该使用Directive、Controller、Service?
    xcode7 The operation couldn't be completed.
    cocoapods pod install 安装报错 is not used in any concrete target
    xcode7 NSAppTransportSecurity
    learning uboot how to set ddr parameter in qca4531 cpu
    learning uboot enable protect console
  • 原文地址:https://www.cnblogs.com/xiaoqingyang/p/6077591.html
Copyright © 2011-2022 走看看