时间:2017-6-27来源:本站原创作者:佚名

看看这个:

intadd(inta,intb)

{

returna+b;

}

doubleadd(doublea,doubleb)

{

returna+b;

}

longadd(longa,longb)

{

returna+b;

}

……

重载为我们提供了方便,只用一个add()可以处理int,double,long等等数据类型,而不用像c语言那样,要为他们去不同的名字,比如addint,adddouble,addlong等等。

不过,这还不够方便!我们要把相同的内容复制粘贴好几次,就像上面那样。

聪明的科学家发明了模板template!

你可以这样写:

#includeiostream

usingnamespacestd;

templatetypenameT

Tadd(Ta,Tb)

{

returna+b;

}

intmain(intargc,char**argv)

{

inta=1,b=2;

coutadd(a,b)endl;

doublec=1.1,d=2.2;

coutadd(c,d)endl;

return(0);

}

template关键字使你能够声明一个模板,然后跟一对尖括号,里面的关键字typename可以换成class,T是你想要替换的类型,他可以是任何类型,甚至是你自己定义写的类型!

typename或class是必须的,标示你替换的是T,而不是别的。

在程序运行时,编译器动态的把add()中的形参匹配为需要的类型,不论是int,还是double。

你甚至可以这样写:

templatetypenameT,typenameS

Tadd(Ta,Sb)

{

returna+b;

}

Main函数这样写:

intmain(intargc,char**argv)

{

inta=1,b=2;

coutadd(a,b)endl;

doublec=1.1,d=2.2;

coutadd(c,d)endl;

coutadd(a,c)endl;

return(0);

}

这样add的两个形参就可以不同了。不过,这里的结果还是int类型,这是默认的类型转换。

哪要处理char类型那?

这个简单!用重载!

templatetypenameT,typenameS

Tadd(Ta,Sb)

{

returna+b;

}

char*add(char*a,char*b)

{

strcat(a,b);//把b复制到a的后面!

returna;

}

intmain(intargc,char**argv)

{

inta=1,b=2;

coutadd(a,b)endl;

charc[]={"abc"},d[]={"def"};

coutadd(c,d)endl;

return(0);

}

结果打印出“abcdef”。

或者,这样写:

templatetypenameT,typenameS

Tadd(Ta,Sb)

{

returna+b;

}

char*add(char*a,char*b)

{

strcat(a,b);//把b复制到a的后面!

returna;

}

classone

{

private:

intonenum;

public:

one(into=0)

{

onenum=o;

}

one(constoneo)

{

onenum=o.onenum;

}

intgetnum()

{

returnonenum;

}

friendostreamoperator(ostreamout,oneo)

{

outo.onenum;

returnout;

}

};

oneadd(onea,oneb)

{

return(a.getnum()+b.getnum());

}

intmain(intargc,char**argv)

{

inta=1,b=2;

coutadd(a,b)endl;

charc[]={"abc"},d[]={"def"};

coutadd(c,d)endl;

oneo1,o2(5),o3(o2);

coutadd(o3,o2)endl;

return(0);

}

不过,这样做意义不大。(我闲的无聊!)

更有意义的是,我们可以把类内的数据成员也用T代换:

templatetypenameT

classone

{

private:

Tonenum;

public:

one(To=0)

{

onenum=o;

}

one(constoneo)

{

onenum=o.onenum;

}

Tgetonenum()

{

returnonenum;

}

friendostreamoperator(ostreamout,oneo)

{

outo.onenum;

returnout;

}

};

intmain(intargc,char**argv)

{

oneinto1;

onefloato2(5),o3(o2);

onedoubleo4(1.2),o5(5.);

couto1endl;

couto2endl;

couto3endl;

couto4endl;

couto5endl;

return(0);

}

使用时,要在类名后的尖括号里加上你想要的类型,让编译器知道应该吧T替换为何种类型!

注意:其他需要的地方也要加上T,不要我写为int!

更进一步:

templatetypenameT,classS//这样也可以的

classone

{

private:

Tonenum;

Stwonum;

intthree;

public:

one(To=0,St=0,inttt=0)

{

onenum=o;

twonum=t;

three=tt;

}

one(constoneo)

{

onenum=o.onenum;

twonum=o.twonum;

three=o.three;

}

Tgetonenum()

{

returnonenum;

}

Sgettwonum()

{

returntwonum;

}

intgetthree()

{

returnthree;

}

friendostreamoperator(ostreamout,oneo)

{

out"a:"o.getonenum()

",b:"o.gettwonum()",c:"o.getthree();

returnout;

}

};

intmain(intargc,char**argv)

{

oneint,into1;

oneint,floato2(5,6.5,1),o3(o2);

onelong,doubleo4(1,1.2,2),o5(2.3,5.,5);//这个2.3输出是多少?

couto1endl;

couto2endl;

couto3endl;

couto4endl;

couto5endl;

return(0);

}

我这里是单文件结构,如果你用的是多文件结构,cpp文件中每个成员函数前面都要加上templatetypenameT,classS,这是必须的!

你可以试试,把onelong,doubleo4(1,1.2,2),o5(2.3,5.,5);替换为onechar,doubleo4(1,1.2,2),o5(2.3,5.,5);

结果是什么?

虽然有了模板,但这不意味着你能随意给T一个类型,你要确保他是有意义的(解决方法我没找到,水平有限,抱歉)!

对于内存分配问题,c++当然解决了。

在你在尖括号中写入类型时,编译器就知道了应该分配多少内存了,这个不用我们担心。

模板的诞生,创造了著名的stl(个人非常喜欢这个东西),泛型编程也随之流行,这深深的影响了业界,在java身上也有他的影子。

-12-:40:58









































治疗白癜风的最佳方法
治疗白癜风医院哪家好

转载请注明原文网址:http://www.gzdatangtv.com/bcyyfz/7337.html
------分隔线----------------------------