天天看點

類模闆,多種類型的類模闆,自定義類模闆,類模闆的預設類型,數組的模闆實作,友元和類模闆,友元函數,類模闆與靜态變量,類模闆與普通類之間互相繼承,類模闆作為模闆參數,類嵌套,類模闆嵌套,類包裝器



類模闆,多種類型的類模闆,自定義類模闆,類模闆的預設類型,數組的模闆實作,友元和類模闆,友元函數,類模闆與靜态變量,類模闆與普通類之間互相繼承,類模闆作為模闆參數,類嵌套,類模闆嵌套,類包裝器

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

繼續閱讀