C++(四十三) — 函数模板机制

 1、普通函数与模板函数调用原则

  1. 函数模板可以像普通函数一样被重载
  2. 当函数模板和普通函数都符合条件时,编译器优先考虑普通函数;
  3. 但如果函数模板产生一个更好的匹配,则选择函数模板;
  4. 可以通过空模板实参列表的语法,限制编译器只通过模板匹配;使用类型列表, max<>(a,b),强制要求使用函数模板;
  5. 当都不满足类型条件时,会调用普通函数;因普通函数的调用,可以进行隐式的类型转换;函数模板的调用,使用类型参数化,严格按照类型进行匹配,不会进行类型的自动转换;

   函数模板本质:

  • 编译器中的汇编,根据函数模板帮程序员生成 不同类型 函数;
  • 具体是进行两次编译:在声明时对模板代码本身进行编译,在调用时对参数替换后的代码进行编译;
  • 函数模板可以和普通函数一样发生重载;

 2、模板类的派生

  需要具体化模板类,知道父类的数据类型,才知道如何分配内存。

class B : public A<int>
{
public:
    B(int a, int b) :A<int>(a)//类模板派生需要重新定义构造函数
    {

    }
private:
    int b;
};

 

3、类模板函数

  在类外声明,友元函数在类外声明(友元函数只用于输入输出的运算符重载,不可用于其他函数)

  如果分开写,函数实现在另一个文件时,类模板函数需要包含 .cpp 文件。

#include <iostream>
#include <typeinfo>
using namespace std;

template <typename T>
class Complex
{
    // 对于友元函数,类模板的运算符重载需要加上  operator<< <T>
    friend ostream & operator<< <T> (ostream &out, Complex &c);
public:
    Complex(T a, T b);
    Complex operator+(Complex &c);

    void printCom();
private:
    T a;
    T b;
};
// 类模板的构造函数,在类的外部
template <typename T>
Complex<T>::Complex(T a, T b)
{
    this->a = a;
    this->b = b;
}
// 模板类的函数,要把  返回的类型具体化参数化
template <typename T>
Complex<T> Complex<T>::operator+(Complex<T> &c)
{
    Complex temp(c.a + a, c.b + b);
    return temp;
}

template <typename T>
void Complex<T>::printCom()
{
    cout << "a: " << a << "\nb: " << b << endl;
}

//友元函数的
// 模板是两次编译的,第一次编译和第二次的生成函数头不一样,
template <typename T>
ostream & operator<< (ostream &out, Complex<T> &c)
{
    out << "a: " << c.a << "\nb: " << c.b << endl;
    return out;
}

void main()
{
    Complex<int> c1(1, 2);
    Complex<int> c2(3, 4);

    Complex<int> c3 = c1 + c2;
    c3.printCom();
    cout << c3 << endl;
    

    system("pause");
}

 

4、类模板中的 static 关键字

  static关键字是属于一个类的,当调用类模板时,每种参数都会调用自己的 static 关键字。

  static T a;

  T AA<T>::a = 0;

 

posted @ 2019-06-04 18:51  深度机器学习  阅读(428)  评论(0编辑  收藏  举报