1.第一個最簡單的類模闆案例
#include
"mainwindow.h"
<qapplication>
<qpushbutton>
<qlabel>
template<class
t>
class
run
{
public:
t
w;
void
show()
w.show();
}
settext()
w.settext("a");
};
int
main(int
argc,
char
*argv[])
qapplication
a(argc,
argv);
run<qpushbutton>
run1;
run1.show();
run1.settext();
return
a.exec();
2.類模闆案例2
#include<iostream>
#include<string>
//定義兩種資料類型的類模闆
//stl資料結構,算法,适合任何類型
t1,class
t2>
myclass
t1
t11;
t2
t22;
myclass(t1
t111,
t222) :t11(t111),
t22(t222)
print()
std::cout
<< t11 <<
"
" <<
t22 <<
std::endl;
main()
myclass<int,
double>
my1(10, 20.8);
my1.print();
myclass<double,
std::string>
my2(20.8,
"123456abc");
my2.print();
std::cin.get();
3.自定義類模闆,類模闆的預設類型
myarray.h
#pragma
once
//隻包含一次,隻是針對vs下的
//類模闆可以有一個預設的值
t =
int>
myarray
myarray();
~myarray();
myarray.cpp
"myarray.h"
template <class
int>//每一個函數都需要加上一個預設的值
myarray<t>::myarray()
//類模闆成員函數在外部,需要加載類型初始化
<< "構造"
<< typeid(t).name()
<< std::endl;
myarray<t>::~myarray()
<< "銷毀"
main.cpp
<iostream>
<array>
<string>
"myarray.cpp"
//類模闆的成員函數沒有執行個體化,不會自動找到,需要手動包含
using
namespace
std;
main1()
myarray<double>
my1;
myarray<>
my2;//c++11的新功能(如果有預設類型了,這時候類型可以為空)
//結果輸出
//構造double
//構造int
array<string,
5>strarray = {
"calc",
"mspaint",
"notepad",
"tasklist",
"pause" };
for (int
i = 0;
i <
strarray.size();i++)
<< strarray[i].c_str()
//運作結果是:
//calc
//mspaint
//notepad
//tasklist
//pause
4.數組的模闆實作(類似c++中array的功能)
array.h
t,int
n>
array
array();
array(int
length);
~array();
size();
get(int
num);
t & operator [](int
num);//重載[]
set(t
data,
t *pt;
array.cpp
"array.h"
t,
n>//int
n不可以修改,不是類的内部成員
array<t,n>::array()
this->pt
= new
t[n];
/*****************************
*初始化length個長度的數組
*****************************/
//每一個函數都必須模闆
array<t,
n>::array(int
length)
t[length];
*析構數組
n>//每一個函數都必須模闆
n>::~array()
//n = 0;
delete[]
this->pt;
*獲得array的大小
*****************************/
n>::size()
n;
*獲得第n個元素
n>::get(int
num)//num是數組的下标
if (num
>= n ||
num < 0)//報錯
//異常
else
return *(this->pt
+ num);
*設定第i個元素的值
n>::set(t
data,int
num)
< 0 || num >=
n)
*(pt +
num) =
data;
*重載[]
t&
n>::operator [](int
return *(pt
測試array的主函數:
"array.cpp"
array<int,
5> myarray;
myarray.size();
i++)
//設定第i個元素的值為i
myarray.set(i,i);
<< myarray[i]
//列印結果是:
//0
//1
//2
//3
//4
/************************************
*通過函數模闆實作列印array中的元素
************************************/
//類模闆作為參數,類型無比明确
print(array<t,
n> &myarray)
myarray.size();i++)
//調用size()函數,求array中的大小
//通過函數模闆實作列印array中的資料
print(myarray);
5.友元類類模闆
//友元類必須聲明類的存在,
//需要聲明友元類,必須要與類型相關
t>
myclass;
runclass;
myclass(t
t) :x(t){}
friend
runclass<t>;//聲明友元類
private:
x;//模闆友元類
runclass
print(const
myclass<t>
& my)
//直接通路傳遞進來的類的私有變量
<< my.x
myclass<double>
my1(19.8);
//myclass中定義的友元類
runclass<double>
run1.print(my1);
6.友元函數
template <class
myclass;
//這裡一定要聲明這個友元類
printa(myclass<t>
my);
t) :x(t)
print(myclass<t>
my)
//友元函數如果在外部,第一聲明要加類型t
//必須要聲明類還有函數
printa<t>(myclass<t>
x;
//模闆友元類
//int y;通路與t無關的類型,普通友元類
myclass<int>
my1(10);
my2(10.9);
printa(my1);
print(my2);
//運作結果:
//10
//10.9
7.類模闆與靜态變量,同種類型的執行個體共享同一個靜态變量,不同類的不共享同一個變量
案例:
//類模闆的static成員,對象,類名《類型》
//不同類型的靜态成員變量,位址不一樣
//相同類型的靜态成員變量,位址一樣
static
num;//聲明
a;
t) :a(t)
num++;
data++;
run()
//this->a;
<< data <<
<< "\n";
int
myclass<t>::num
= 0;
myclass<t>::data
//靜态變量,靜态函數,同種類型的時候共享的靜态變量
//類型不同,不共享靜态變量
my4(10);
myclass<int>::run();
my1.run();
myclass<double>::run();
//int
//double
myclass<int
> my1(10);
myclass<double
> my2(10.9);
myclass<std::string
> my3("1234");
> my4(10);
<< &my1.num
<< &my2.num
<< &my3.num
<< &my4.num
<< &myclass<int
>::num <<
<< &myclass<float
8.類模闆之間的繼承
//模闆類之間的繼承
//類模闆可以直接繼承類模闆,類型必須傳遞
//普通類繼承類模闆,需要明确類型執行個體化類模闆
//類模闆繼承普通類,正常的操作方式
//類模闆當作普通哦類,需要模闆參數對類進行執行個體化
t>
//抽象模闆類
x;
virtual
print() = 0;
newclass :public
//繼承必須明确類型
y;
newclass(t
t1,
t2) :myclass(t1),
y(t2)
//調用父類的構造函數
<< x <<
"
y <<
*p =
new
newclass<int>(10,9);
p->print();
//運作結果是:10
9
當寫成下面的函數時
newclass<std::string>
my1("abc",
"xyz");
//運作結果是:abc
xyz
9.類模闆繼承普通類,普通類繼承類模闆等情況
print() = 0;
//可以帶有純虛函數
//普通類
z;
xyz(int
a,
b,
c) :x(a),
y(b),
z(c)
newxyz :public
//構造的時候給父類初始化
newxyz(t
a1,
b1,
c1) :xyz(a1,
c1),
a(t1)
<< "ta=" <<
a <<
z <<
/*普通類繼承模闆類的時候這是要确定類型*/
classrun :public
newxyz<int>
d = 1000;
//下面的構造函數要确定類型
classrun(int
a2,
b2,
c2,
d2) :newxyz<int>(a2,
d2)
<< d <<
x <<
classrun
run1(1, 2, 3, 4);
run1.print();
//運作結果是:10002341
std::string
str1 =
"china";
newxyz<std::string>
new1(str1,
10, 90, 89);
new1.print();
//ta=china
//109089
10.類模闆與友元函數,類模闆與友元類
<vector>
& my,
t1);
//friend void print(myclass<t> & my,t t1);
//友元函數放在模闆類的内部,實作重載
myclass *
operator+(const
& my1,
const
& my2)
//下面的情況在棧上,用完了馬山釋放
//myclass class1
//堆上申請一個
p =
myclass(my1.x
+ my2.x,
my1.y
+ my2.y);
p;
t2) :x(t1),
//通路私有需要友元
t1)
<< typeid(t1).name()
<< "
my.y
my1(19, 29);
vector<int>
v1;
vector<vector<int>>
v2;
vector<vector<vector<int>>>
v3;
//通過下面的方式對類型進行簡寫
vec =
vector<vector<vector<int>>>;
//c++11簡寫
vec
v4;//等價于三維int類型資料,模闆
案例2
//這裡要聲明模闆類和友元函數
object;
fun(const
object<t>
&);
object
_d;
object(t
d) :_d(d){}
//聲明友元函數
fun<t>(const
& obj)
cout <<
obj._d
<< endl;
object<double>
obj(111.4);
fun<double>(obj);
return 0;
//運作結果:111.4
類模闆與友元類
//定義友元類和友元函數
//友元必須類名
print<t>(const
runclass<t>;
&my)
<< "
my2(11,1);
runclass<int>
runclass1;
runclass1.print(my1);
//11
1
//19
29
11.類模闆當作模闆參數
//類模闆當作一個類的參數
//設計stl的時候用到
ren
//一個通用的類的類模闆
name;
ren(t
t) :name(t)
//使用類模闆當作模闆參數的類
template<template<class
t1>
people
t1<string>
t1x =
"123123";//t1必須執行個體化
。必須結合
t1<string>
num =
"abc";
//等價于ren類型
//t1 x
people(t1<string>
&t1)
<< t1.name
t1;
ren<string>
ren1("hello8848");//基本資料類型
people<ren>
people1(ren1);
//嵌套的類模闆
<< people1.t1x.name
<< people1.num.name
<< ren1.name
運作結果:
12.類包裝器
//類包裝器,實作一個操作接口,操作多個類的方法
template<typename
t,typename
f>
run(t
f
f)
f(t);
add(int
num + 10;
num;
myclass(int
data) :num(data)
int operator ()(int
x)
x*num;
myclassa
myclassa(int
<< "a\n";
x -
my1(5);
//函數作為參數
<< run(101,
my1) <<
//函數作為參數,下面的重載調用了()操作符
myclassa(51)) <<
//505
//a
//50
auto
num = 100;
func =
add;
//調用add函數
<< run(num,
add) <<
//運作結果:110
13.類嵌套
//類的嵌套
newclass
} new1;
newnewclass :public
newnewclass
newx;
newx.myclass::new1.num
= 10;
<< newx.new1.num;
//運作結果:10
myclass1;
myclass1.new1.num
= 19;
<< myclass1.new1.num;
//運作結果:19
14.類模闆嵌套
} new1;
//定義的方式
new2;
v>
v
};//類模闆後面不可以直接初始哈
runclass<t>
t2;
my1.new1.num
//給嵌套類中的變量指派
my1.t1.v1
= 12;
my1.t2.v1
= 12.9;
<< my1.t1.v1
<< "\n" <<
my1.t2.v1;
//12
//12.9