C++语言基础(18)-模板

Java中的泛型编程可以极大的提升编程的效率,比如在android中查找一个控件的ID:标准写法为:

TextView tv_text = (TextView)findViewById(R.id.tv_text);

或者:

ImageView iv_img = (ImageView)findViewById(R.id.iv_img);

因为同为查询控件ID,所以上面的写法可以采用泛型编程精简为:

protected final <T extends View> T getView(int id) {
        return (T) findViewById(id);
}

这样在下次使用的时候就可以写成这样:

TextView tv_text = getView(R.id.tv_text);

C++中也有类似的东西,不过名字变了,叫模板(template)

一.函数模板

例:交换两个相同类型变量的值

原始写法:

//交换 int 变量的值
void Swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

//交换 float 变量的值
void Swap(float *a, float *b){
    float temp = *a;
    *a = *b;
    *b = temp;
}

//交换 char 变量的值
void Swap(char *a, char *b){
    char temp = *a;
    *a = *b;
    *b = temp;
}

//交换 bool 变量的值
void Swap(bool *a, bool *b){
    char temp = *a;
    *a = *b;
    *b = temp;
}

使用模板后的写法:

#include <iostream>
using namespace std;

template<typename T> void Swap(T *a, T *b){
    T temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
    //交换 int 变量的值
    int n1 = 100, n2 = 200;
    Swap(&n1, &n2);
    cout<<n1<<", "<<n2<<endl;

    //交换 float 变量的值
    float f1 = 12.5, f2 = 56.93;
    Swap(&f1, &f2);
    cout<<f1<<", "<<f2<<endl;

    //交换 char 变量的值
    char c1 = ‘A‘, c2 = ‘B‘;
    Swap(&c1, &c2);
    cout<<c1<<", "<<c2<<endl;

    //交换 bool 变量的值
    bool b1 = false, b2 = true;
    Swap(&b1, &b2);
    cout<<b1<<", "<<b2<<endl;

    return 0;
}

修改成引用:

#include <iostream>
using namespace std;

template<typename T> void Swap(T &a, T &b){
    T temp = a;
    a = b;
    b = temp;
}

int main(){
    //交换 int 变量的值
    int n1 = 100, n2 = 200;
    Swap(n1, n2);
    cout<<n1<<", "<<n2<<endl;

    //交换 float 变量的值
    float f1 = 12.5, f2 = 56.93;
    Swap(f1, f2);
    cout<<f1<<", "<<f2<<endl;

    //交换 char 变量的值
    char c1 = ‘A‘, c2 = ‘B‘;
    Swap(c1, c2);
    cout<<c1<<", "<<c2<<endl;

    //交换 bool 变量的值
    bool b1 = false, b2 = true;
    Swap(b1, b2);
    cout<<b1<<", "<<b2<<endl;

    return 0;
}

例:求三个数最大值:

#include <iostream>
using namespace std;

//声明函数模板
template<typename T> T max(T a, T b, T c);

int main( ){
    //求三个整数的最大值
    int i1, i2, i3, i_max;
    cin >> i1 >> i2 >> i3;
    i_max = max(i1,i2,i3);
    cout << "i_max=" << i_max << endl;

    //求三个浮点数的最大值
    double d1, d2, d3, d_max;
    cin >> d1 >> d2 >> d3;
    d_max = max(d1,d2,d3);
    cout << "d_max=" << d_max << endl;

    //求三个长整型数的最大值
    long g1, g2, g3, g_max;
    cin >> g1 >> g2 >> g3;
    g_max = max(g1,g2,g3);
    cout << "g_max=" << g_max << endl;

    return 0;
}

//定义函数模板
template<typename T>  //模板头,这里不能有分号
T max(T a, T b, T c){ //函数头
    T max_num = a;
    if(b > max_num) max_num = b;
    if(c > max_num) max_num = c;
    return max_num;
}

运行结果:

12  34  100
i_max=100
73.234  90.2  878.23
d_max=878.23
344  900  1000
g_max=1000

总结一下,函数模板的基本语法为:

template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型  函数名(形参列表){
    //在函数体中可以使用类型参数
}

二.类模板

类模板的声明与函数模板的声明类似:

template<typename 类型参数1 , typename 类型参数2 , …> class 类名{
    //TODO:
};

示例代码:

#include <iostream>
using namespace std;

template<class T1, class T2>  //这里不能有分号
class Point{
public:
    Point(T1 x, T2 y): m_x(x), m_y(y){ }
public:
    T1 getX() const;  //获取x坐标
    void setX(T1 x);  //设置x坐标
    T2 getY() const;  //获取y坐标
    void setY(T2 y);  //设置y坐标
private:
    T1 m_x;  //x坐标
    T2 m_y;  //y坐标
};

template<class T1, class T2>  //模板头
T1 Point<T1, T2>::getX() const /*函数头*/ {
    return m_x;
}

template<class T1, class T2>
void Point<T1, T2>::setX(T1 x){
    m_x = x;
}

template<class T1, class T2>
T2 Point<T1, T2>::getY() const{
    return m_y;
}

template<class T1, class T2>
void Point<T1, T2>::setY(T2 y){
    m_y = y;
}

int main(){
    Point<int, int> p1(10, 20);
    cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl;

    Point<int, char*> p2(10, "东京180度");
    cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl;

    Point<char*, char*> *p3 = new Point<char*, char*>("东京180度", "北纬210度");
    cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl;

    return 0;
}

输出结果:

x=10, y=20
x=10, y=东京180度
x=东京180度, y=北纬210度

注意:

1.在对类模板的成员函数进行定义时,除了 template 关键字后面要指明类型参数,类名 Point 后面也要带上类型参数,只是不加 typename 关键字了

2.类模板在实例化时必须显式地指明数据类型,赋值号两边也要指明具体的数据类型,且要保持一致

时间: 2024-10-14 07:32:28

C++语言基础(18)-模板的相关文章

02 java语言基础

常量:字面值常量(字符串,字符,整数,小数,布尔,null),自定义常量,''这个不是字符常量,""这个是字符串常量 进制: 02.01_Java语言基础(常量的概述和使用)(掌握) A:什么是常量 在程序执行的过程中其值不可以发生改变 B:Java中常量的分类 字面值常量 自定义常量(面向对象部分讲) C:字面值常量的分类 字符串常量 用双引号括起来的内容 整数常量 所有整数 小数常量 所有小数 字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号 布尔常量 较为特

R语言基础

##数据获取 x1=round(runif(100,min=80,max=100)) x2=round(rnorm(100,mean=80, sd=7)) x3=round(rnorm(100,mean=80,sd=18)) x3[which(x3>100)]=100 num=seq(2005138101,length=100) x=data.frame(num,x1,x2,x3) write.table(x, "grade.txt") ##数据分析 y=read.table(&

C#语言基础知识(2):C#中多态

我的理解是:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态. 1: OverRide 实现多态 1 public class Animal 2 { 3 public virtual void Eat() 4 { 5 Console.WriteLine("Animal eat"); 6 } 7 } 8 public class Dog : Animal 9 { 10 public override void Eat() 11 { 12 Console.WriteLin

03 java语言基础逻辑运算符

03.01_Java语言基础(逻辑运算符的基本用法)(掌握) A:逻辑运算符有哪些 &,|,^,! &&,|| B:案例演示 逻辑运算符的基本用法 注意事项: a:逻辑运算符一般用于连接boolean类型的表达式或者值. b:表达式:就是用运算符把常量或者变量连接起来的符合java语法的式子. 算术表达式:a + b 比较表达式:a == b(条件表达式) C:结论: &逻辑与:有false则false. |逻辑或:有true则true. ^逻辑异或:相同为false,不同

嵌入式linux C++语言(二)——C++对C语言基础语法的扩展

嵌入式linux C++语言(二)--C++对C语言基础语法的扩展 C++是基于C语言扩展发展而来的面向对象的程序设计语言,本文将主要讨论C++语言基于C语言扩展的方面. 一.类型增强 1.类型检查更严格 在C语言中: const int a = 100; int *p = &a; 在C++语言中: const int a = 100;//必须在定义的时候初始化 const int *p = &a; 在C++语言中不能隐式转换数据类型. error: invalid conversion

OC基础(18)

Category基本概念 Category注意事项 *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: p

C#语言基础知识(1):C#中关于重载和重写

Overload:重载就是在同一个类中,方法名相同,参数列表不同.参数列表不同包括:参数的个数不同,参数类型不同. 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace OverLoading 6 { 7 class Program 8 { 9 public static int max(int i, int j) //静态方法 10 { 11 if (i > j) 12 re

C语言基础(转载自大海笔记)

# C语言基础2015年03月26日10:04:411.    语言排行榜C——java——objective-C2.    进制:进制:进位机制.用普通的话讲,应该为人为的定义一种度量来标识一样东西.计算机常用的进制有:十进制.二进制.八进制和十六进制.?    十进制:0-9(十个指头)(进制表示基数:10)?    二进制:0,1(基数为2)?    八进制:0-7(基数为8)?    十六进制:0-9,A-F(基数为16)    可以有很多进制,比如分钟为60进制等等.3.    位权为

java--java语言基础(3)--黑马程序员

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- java语言基础(3) 主要内容:<运算符.键盘录入.顺序结构.选择结构if.三元运算符.选择结构switch.> 1 位运算符的基本用法1 位运算符:是对整数的二进制直接进行操作的 1.<< : 左移:左侧高位丢弃,右侧补0.左移一位,相当于原数 * 2 ; 实际移动的位数 = 要移动的位数 % 32; 2.>> : 带符号右移:右移一位,右侧的最低位丢弃,左侧高位