首页 > 其他分享 >六. 函数模板和类模板

六. 函数模板和类模板

时间:2023-12-04 17:23:12浏览次数:31  
标签:函数 int template 类型 array 模板

文章参考:

《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)_白鳯的博客-CSDN博客

1. 引入

在编写函数和类时,有时会出现这样的情况,具体实现方式完全一致,但因此参数类型、返回值类型、数据类型等因素的不同,导致不得不写多个函数或者类(因为C++是强类型语言,无法隐式转换,且有些类型本来就无法转换),这样无疑会增加操作难度。那么,如何简单的完成这一任务呢?

define是一个办法,例如:

#define MAX(x,y) ((x>y) ? x : y);

这样就避免了因数据类型不同而重复编写代码。

但是,define可能导致代码在不该替换的地方进行了替换,从而造成错误,因此C++中不主张使用宏定义。

所有一个更好的办法就是使用模板。

2. 函数模板

声明格式:有两种方式:

  •   template <typename 类型参数>
      返回类型 函数名(模板形参表)
      {
          函数体
      }
    
  •   template <class 类型参数>
      返回类型 函数名(模板形参表)
      {
          函数体
      }
    

可以定义多个类型参数:

  •   template <typename 类型参数1, typename 类型参数2,>
      返回类型 函数名(模板形参表)
      {
          函数体
      }
    

EG:

  • 问题:求当前数组中最大的值。

  • 代码:

    #include <iostream>
    using namespace std;
    
    template <typename T>			// template <class T> 也可以
    T Max(T *array, int size = 0) {
    	T max = array[0];
    	for (int i = 1	; i < size; i++) {
    		if (array[i] > max) max = array[i];
    	}
    	return max;
    }
    
    int main() {
    	int array_int[] = {783, 78, 234, 34, 90, 1};
    	double array_double[] = {99.02, 21.9, 23.90, 12.89, 1.09, 34.9};
    	int imax = Max(array_int, 6);
    	double dmax = Max(array_double, 6);
    	cout << "整型数组的最大值是:" << imax << endl;
    	cout << "双精度型数组的最大值是:" << dmax << endl;
    	return 0;
    }
    

注意:

  • template语句和函数语句中不允许插入别的语句。
  • 在函数模板中允许使用多个类型参数。但是,应当注意template定义部分的每个类型参数前必须有关键字typenameclass
  • 函数模板也可以重载。
  • 函数模板与同名的非模板函数可以重载。在这种情况下,调用的顺序是:
    1. 寻找一个完全匹配的非模板函数。
    2. 如果找不到,再找函数模板。

3. 类模板

建立类模板,主要是因为有时候,类的数据类型、成员函数的返回类型、形参类型不确定,因此使用类模板。语法与函数模板相似。下面是一个案例:

template <typename T>
class Three{
private:
    T x, y, z;
public:
    Three(T a, T b, T c) {
        x = a; y = b; z = c;
    }
    T sum() {
        return x + y + z;
    }
    T mul();
}
// 如果在类外定义类模板的成员函数,需要加上模板声明,且函数名前要加上"类名<类型参数>::"
template <typename T>
T Three<T>::(){
	return x * y * z;
}

EG:

  • 代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int CAPACITY = 10;
    
    template <typename T>
    class Stack{
    private:
        T stack[CAPACITY];      // 这里使用数组,简化初始化操作
        int top;
    public:
        void init();
        void push(T t);
        T pop();
    };
    
    // 必须加上<T>定义,否则无法识别类
    template <typename T>
    void Stack<T>::init(){
        top = 0;
    }
    
    template <typename T>
    void Stack<T>::push(T t){
        if(this->top == CAPACITY){
            cout << "stack is full"<< endl;
            return;
        }
        stack[top++] = t;
    }
    
    template <typename T>
    T Stack<T>::pop(){
        if (top == 0){
            cout << "stack is empty" << endl;
            return 0;
        }
        return stack[--top];
    }
    
    int main(void){
        // 注意:在初始化模板类时需要指定参数类型
        Stack<int> s;
        s.init();
        s.push(3);
        s.push(5);
        cout << s.pop() << endl;
        cout << s.pop() << endl;
        cout << s.pop() << endl;
        return 0;
    }
    
  • 输出:

    5
    3
    stack is empty
    0
    

注意:

  • 只要是模板类的类外声明,在类名后面都必须加上<类型参数>
  • 使用模板类时,要指定该模板类的参数类型。

标签:函数,int,template,类型,array,模板
From: https://www.cnblogs.com/beasts777/p/17875459.html

相关文章

  • C++ 内联函数 inline
    宏定义实现和普通函数实现:-宏定义是直接在实现的时候进行代码替换,可能产生结果异常问题。-普通函数实现:调用函数进出函数体的时候时间开销可能过大。1#include<iostream>2usingnamespacestd;3//宏实现4#defineGETMAX(a,b)((a)>(b)?(a):(b))......
  • Java 函数式接口
    在Java中,函数式接口(functionalinterface)是指仅包含一个抽象方法的接口。这种类型的接口通常用于表示简单的函数签名,并可与lambda表达式或方法引用结合使用,从而提供一种更简洁、更灵活的编程方式。Java8引入了函数式接口的概念,以及一个新的注解@FunctionalInterface。这个注解......
  • vue3 setup 父组件向子组件传递参数、方法|子组件向父组件传递数据,函数
    https://blog.csdn.net/qq_27517377/article/details/123163381https://blog.csdn.net/qq_27517377/article/details/123166367vue3setup父组件向子组件传递参数参数<template><el-rowclass="mb-4"> <el-buttontype="danger">props.vue传......
  • 无涯教程-Erlang - atan函数
    该方法返回指定值的反正切。atan-语法atan(X)X - 为反正切函数指定一个值。atan-返回值返回值是一个浮点值,表示反正切值。-module(helloLearnfk).-import(math,[atan/1]).-export([start/0]).start()->Atan=atan(0.7071),io:fwrite("~p~n",[Atan]......
  • Python函数介绍
    1.函数1.1函数概述函数定义和优势不同形状正方形打印#2个foriinrange(0,2):forjinrange(0,2):print("*",end="")print()#3个foriinrange(0,3):forjinrange(0,3):print("*",end="")pr......
  • MySQL部分函数
    单行函数数值函数基本函数函数用法ABS(x)返回x的绝对值SIGN(X)返回X的符号。正数返回1,负数返回-1,0返回0PI()返回圆周率的值CEIL(x),CEILING(x)返回大于或等于某个值的最小整数FLOOR(x)返回小于或等于某个值的最大整数LEAST(e1,e2,e3…)返回......
  • 无涯教程-Erlang - sin函数
    此方法返回指定值的正弦值。sin-语法sin(X)X - 为正弦函数指定一个值。sin-返回值返回值是代表正弦值的浮点值。-module(helloLearnfk).-import(math,[sin/1]).-export([start/0]).start()->Sin=sin(45),io:fwrite("~p~n",[Sin]).当我们运行上......
  • 字典树模板
    #include<bits/stdc++.h>usingnamespacestd;structtrie{intn;vector<array<int,26>>trans;vector<int>cnt;trie():n(0){new_node();}intnew_node(){trans.push_back({});trans.back()......
  • 无涯教程-Erlang - 嵌套if函数
    有时,需要相互之间嵌入多个if语句,这在其他编程语言中也是可能的。在Erlang中,这也是可能的。Nestedif-示例-module(helloLearnfk).-export([start/0]).start()->A=4,B=6,ifA<B->ifA>5->io:fw......
  • 关于函数宏offset_of 和 container_of的学习
    #defineoffset_of(type,member)((unsignedint)&((type*)0)->member)#definecontainer_of(ptr,type,member)((type*)((char*)(ptr)-offset_of(type,member)))offset_of(type,member)用途:用于获取获取结构体某一个成员在该结构体中的位置参数1:type,表示......