你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++——类模板的概念学习

[复制链接]
gaosmile 发布时间:2020-8-26 22:15
一、类模板的引出:
1、在c++中是否能够将泛型的思想应用在类上呢?
我们在前面的两篇文章里面,对函数模板有了一个清楚的认识,作为类比学习,当然泛型的思想是可以应用到类上的。
2、类模板:
  • 一些类主要用于存储和组织数据元素
  • 类中数据组织的方式和数据元素的具体类型无关
  • 如:数组类,链表类,Stack类,Queue类等等
  • c++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能

    4 Y9 P( ?  ^" C: a+ v
3、C++中的模板:
以相同的方式处理不同的类型
在类声明前使用template进行标识
template < typename T >//T表示泛指类型
, l3 V" ?+ @- p& p
( ?/ }# a4 S2 o( P$ Q+ V3 d2 Sclass Operator
4 {$ H" x3 c* `! M" R. [  Z{/ \/ w. _" Z' b8 A2 M
   public:
. W9 t# }5 W+ q; O% W: j0 w      T op(T a , T b);
. O+ f# L; \5 L};6 i) z) K; z( J' ^
4、类模板的应用
  • 只能显示指定具体类型,无法自动推导(我们的函数模板是可以实现自动推导具体类型的)

    ) r! \) E+ [! S! s
//使用具体类型"<Type>"定义对象
) R9 A! I+ p' ]# I% lOperator<int> op1;. w& n4 ?  n+ q/ C
Operator<string> op2;
" n% K! {" y1 d, G) d! h2 P4 x2 F* X5 S2 R" Y' p6 u" w
int i = op1.op(1,2);. k- }+ M: A# a' U! w
string s = op2.op("txp","C++");
5 v4 R" G- B1 O; d! e4 U2 N4 Z9 b: a  8 _9 p1 {; F; I$ x# |# I0 _2 G2 H
  • 声明的泛指类型T可以出现在类模板的任意地方
    7 {4 [3 L/ a/ E4 g3 k9 D
  • 编译器对类模板的处理方式和函数模板相同

    ) \* k# c- |6 ~% S0 A- V
-从类模板通过具体类型产生不同的类
-在声明的地方对类模板代码本身进行编译
-在使用的地方对参数替换后代码进行编译
代码实践:
#include <iostream>  s2 G; N% r& b+ c* ~% G% i7 m
#include <string>  K* y% l$ y. c# `  @; G3 A

6 [' g9 L" D7 _1 Y5 A1 e& K+ }& Kusing namespace std;
  _  t$ r2 L8 a" V
5 L. T* K6 Z9 i8 Htemplate < typename T >& z9 ^& U5 Q( j9 W
class Operator
& |  T0 R+ F! H- z{
. L$ E7 ?/ i8 Jpublic:
4 U# v! |9 L! I* J$ v# B2 f  M    T add(T a, T b)
* ?3 ^- U$ D; ]. H7 U    {
/ m  x# |' y) I! R0 r        return a + b;( }  |# J8 H! v: R. s; C
    }
3 ?* w5 o8 F+ Q+ `( x( f    T minus(T a, T b)7 ^( P+ `) E3 L
    {* d. N+ ~( d( h6 t5 F) Z
        return a - b;
1 m1 T- e$ n. t  a    }
7 {8 P! Z% ]5 Y8 N1 F* p    T multiply(T a, T b)7 x2 T7 G3 ^4 g
    {9 ~( V- N4 [, Q$ M% {9 H
        return a * b;6 J! s: ~7 b0 R# y* V! i  e
    }6 j8 R5 z  x8 m/ N9 O$ l, t# n, }2 E
    T divide(T a, T b)
3 h1 _# y6 b5 ], F    {6 A- f) A. c$ O
        return a / b;) O3 \8 j% y" y) Y* v8 t
    }
/ F$ x: ^7 k* i) r};( t6 n! h+ \" G

  q/ U2 \2 J. N& g$ t+ [6 B+ m9 Wstring operator-(string& l, string& r)// 全局函数方式重载 - 操作符,编译通过;先类内部、再全局
7 ]$ W! |5 k1 S9 E6 O# z{
0 b6 Z& S" g& p* G* Q    return "Minus";! }; S% Z6 c3 Q1 u) U! `2 j
}
, z0 x# V7 |. `9 a9 M5 j  g3 ~! p% F% s/ x, \' M
int main()
1 s/ E2 {* S* `& o, _+ s6 F{6 b  E: }; n$ W* {
    Operator<int> op1;) H* `, }- f8 E) P4 ]
      R5 [* l8 u6 ?
    cout << op1.add(1, 2) << endl;
% t" q' }# {2 C; D. ~, N- t   
2 j( b# W5 W! V$ _* v8 w- M    Operator<string> op2; // 第二次使用类模板时进行编译,但是并不是对所有模板中的函数进行了第二次编译,是分步编译的,首先编译的是构造函数,此时用的是默认的,没有问题,这里编译通过;
" J* F+ j" B  M7 c3 z   
5 V7 J1 c) a. c" e/ F- u2 V% X    cout << op2.add("Txp", "C++") << endl;4 x; T% K, ?8 F# b
    cout << op2.minus("Txp", "C++") << endl; // 如果没有定义全局的重载 - 操作符的函数时,字符串相减没有定义,报错;这里报错展示出来是为了证明类模板编译也是经过了两次编译;这里编译器针对 minus() 函数进行第二次编译;定义全局的重载 - 操作符函数后,打印 Minus ;
! y% {9 F: K! i% ?9 r% k   
) [+ C0 C4 u& R" g/ z, t. y    return 0;/ }7 }. ?; s7 N3 C
}
6 c: Q8 N5 s. i6 V5 y* B& W4 v" e2 B5 e* A- [

! d" i! d6 K+ R$ }. c! j( C3 d/ m1 X
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
" w, ?2 K: i4 x0 q8 `& V" V, o3
. d2 M. L1 J4 H5 z) W5 U  nTxpC++) a3 ]# q2 s! \5 m2 T
Minux
! o  P, G, c4 I) Z0 a( Y2 H8 I% x9 E, D
5、类模板的工程应用
  • 类模板必须在头文件中定义
  • 类模板不能分开实现在不同的文件中
  • 类模板外部定义的成员函数需要加上模板<>声明

    3 d5 b; I" P3 y) y+ q
代码实践:
Operator.h头文件:
#ifndef _OPERATOR_H_
6 C0 ]' C' _. ^% {5 }$ X; |#define _OPERATOR_H_
3 ?/ l& S6 d2 }6 N
" R8 Z. Q; K1 y5 Ktemplate < typename T >
5 c0 u/ r3 W6 Uclass Operator" H' H' w/ n2 n( {: f
{& C: w- l+ C1 y6 q
public:
1 e: J- m8 i$ I0 @4 R* b    T add(T a, T b);
, f5 [9 \+ {( \0 f# C) v    T minus(T a, T b);
# [, a& w. o, @1 U    T multiply(T a, T b);
* X: `8 q% }0 y; _    T divide(T a, T b);1 {# `' b3 m1 |- R* D% F
};
* ]- u2 m9 L- J6 T# R8 [/ w1 x- T5 k* o7 D) |& _
template < typename T >' @" h5 D8 o" K9 D
T Operator<T>::add(T a, T b)& s) i. {; M3 f1 [
{  R$ Z2 z4 G# A4 I. ]1 T  A- q8 T/ R! v
    return a + b;
& j; k! U# h) ]: U+ Y}5 d/ Y/ ]5 p1 T& i

; g5 b3 Y& e9 u3 J+ P, G3 F6 _: O- I" B9 c1 C) t" b
template < typename T >
; [/ O" @4 p7 g, L7 L; aT Operator<T>::minus(T a, T b): @! \/ G  y9 g! ?
{
# m) a$ @  I' E. V% y2 T    return a - b;
" O, A# Q4 G* C* S}, G2 h& ]% q; j7 L9 D$ ?
' _5 }& `8 x9 D. r! L
  I) E; f8 q  j1 f, S7 u+ V3 b
template < typename T >
- r9 \/ T1 M: K$ O  ^9 eT Operator<T>::multiply(T a, T b)0 X( |1 L( N; x% `8 d  q
{; v. k* d* d3 U) Q6 z
    return a * b;
* k& [9 Q8 v) M* e" i( r}' }+ Y# V/ h5 p( j

4 Z/ k& a, G5 m) X+ @. I' Y5 |# u; ~8 c7 z( `( c
template < typename T >
9 R% u$ `$ z! M/ C8 b4 @T Operator<T>::divide(T a, T b)
% M' d* D- X+ Q# }! V0 _{! ^+ Z: U' H; F
    return a / b;4 G9 B! X3 W! Z3 @) h
}) q3 \) {5 j; J1 O/ k* _

" \% e0 y, O* @1 j7 O- g#endif
0 m. a  c( j& [( L
test.cpp文件:
#include <iostream>- ]8 m. [4 ?1 J9 P9 ~
#include <string>3 B  G- @- {3 G* H
#include "Operator.h"
. {* |1 S/ h* d# B1 [' V7 Y
2 B2 J/ C0 k$ ]" vusing namespace std;; S9 \' ^+ o9 M2 c- H# @' k
& R2 L) L4 m7 `2 U  X
6 `1 l8 T8 l1 d, W; H6 l
int main()
3 r! ^6 C: s6 t1 [/ j- I{
' Y; q+ H8 h' q. |0 @5 O9 F    Operator<int> op1;
$ U6 a+ o1 }& z/ {/ C. @    % U/ E% \% B) u$ I: U' b! G, o
    cout << op1.add(1, 2) << endl;" B* O- z5 a; d3 L6 v, u
    cout << op1.multiply(4, 5) << endl;
+ ~1 P: O# c" `! ]    cout << op1.minus(5, 6) << endl;& \1 U: R8 l- N# t! t
    cout << op1.divide(10, 5) << endl;$ H$ F% H9 d5 f1 i
    0 S' ]# I2 x5 m3 j: b) T; h
    return 0;
% \; O' D& @/ \, Q2 c}, n' c0 q) J& H" `+ [# {0 F- ^
+ s$ s  V) s0 a5 h0 E5 r

# G. J1 P: q( {5 b2 V
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
# o  ]* ^( k) J8 }, r3
% C9 ?4 h5 t, d1 [) {& ~+ u( Q" d. |20+ b- `( h3 n7 \( F( {/ ]- s
-1* B( i+ R( I, U
2, }/ |# [! @+ b* d  N9 S

) r( |! k( p$ W6 H+ j
二、总结:
  • 泛型编程的思想可以应用于类
  • 类模板以相同的方式处理不同的类型的数据
  • 类模板非常适用于编写数据结构相关的代码
  • 类模板在使用时只能显示指定类型

    3 X2 g1 P; R" I7 x
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。
* A/ [& r/ {2 G# |8 n
赞 收藏 评论0 发布时间:2020-8-26 22:15

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版