看看这个: 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 |