56星座屋
当前位置: 首页 星座百科

c++类模板的使用(c++入门代码)

时间:2023-05-30 作者: 小编 阅读量: 2 栏目名: 星座百科

c++类模板的使用?例子1复数类—-所有函数写的类的内部,下面我们就来聊聊关于c++类模板的使用?接下来我们就一起去了解一下吧!)关于类模板的几点说明1)类模板的类型参数可以有一个或多个,每个类型前面都必须加class,如:template<classT1,classT2>classsomeclass{……

c++类模板的使用?例子1 复数类—-所有函数写的类的内部,下面我们就来聊聊关于c++类模板的使用?接下来我们就一起去了解一下吧!

c++类模板的使用

例子1 复数类—-所有函数写的类的内部

#include<iostream>using namespace std;template<typename T>class Complex{firend ostream & operator<<(ostream &out, Complex &c3){cout << "a:" << " + " << "b:" << c3.b << endl;return out;}public:Complex(T a=0,T b=0);{this->a = a;this->b = b;}Complexoperator+(Complex &c2){Complex tmp(a + c2.a, b + c2.b);return tmp;}void printComplex(){cout << "a:" << a << "b:" << b << endl;}private:Ta;Tb;};//运算符重载的正规写法,重载<<>>只能用友员函数,其他运算符重载,都要写成成员函数,不要滥用友员函数void main(){//需要把模板类进行具体化以后,才能定义对象,c++编译器要分配内存Complex<int>c1(1,2);Complex <int>c2(3, 4);Complex<int>c3=c1+c2;cout << c3 << endl;system("pause");return;}

例子2 复数类—-所有函数写的类的外部,但在一个cpp里

#include<iostream>using namespace std;template<typename T>class Complex{firend ComplexMySub<<(Complex &c1, Complex &c2){Complex tmp(a + c2.a, b + c2.b);return tmp;}firend ostream & operator<< <T> (ostream &out, Complex &c3);public:Complex(T a, T b)Complexoperator+(Complex &c2)void printComplex();private:Ta;Tb;};template<typename T>//构造函数的实现,写在了类的外部Complex<T>::Complex(T a,T b){this->a = a;this->b = b;}template<typename T>voidComplex::printComplex(){cout << "a:" << a << "b:" << b << endl;}template<typename T>Complex<T> Complex<T>::operator+(Complex<T> &c2)//成员函数实现+运算符重载{Complex tmp(a + c2.a, b + c2.b);return tmp;}template<typename T>ostream & operator<<(ostream &out, Complex<T>&c3)//友员函数实现运算符重载{cout << "a:" << " + " << "b:" << c3.b << endl;return out;}void main(){Complex<int>c1(1, 2);Complex <int>c2(3, 4);Complex<int>c3 = c1 + c2;cout << c3 << endl;system("pause");return;}

归纳以上的介绍,可以这样使用.声明类模板

1)先写出一个实际的类.由于其语义明确,含义清楚,一般不会出错.

2)将此类中准备改变的类型名(如int 要改为char)改用一个自己指定的虚拟类型名字

3)在类声明前加入一行,格式为:

template<class 虚拟类型函数>//注意本行末尾无分号

4)用类模板定义对象使用以下形式:

类模板名<实际类型名>对象名

类模板名<实际类型名>对象名(实参列表)

如:

Compare<int> cmp;

Compare<int> cmp(3,4);

5)如果在类模板外定义成员函数,应该写成类模板形式:

template<class 虚拟类型函数>

函数类型 类模板名<虚拟函数参数>::成员函数名(参数形参列表)(……)

关于类模板的几点说明

1)类模板的类型参数可以有一个或多个,每个类型前面都必须加class,

如:

template<class T1,class T2>

class someclass

{……}

定义对象时分别带入实际的类型名,如;

someclass<int,double>obj;

2)和使用类一样,使用类模板时要注意其作用域,只能在其有效作用域内用它定义对象.

3)模板可以有层次,一个类模板可以作为基类,派生出派生类的模板,有关这方面的知识实际应用比较少,感兴趣的可以自行查阅.

类模板中的ststic关键字

从类模板比例实例化的每个模板类都有自己的类模板数据成员,该模板类的所有对象共享一个

ststic数据成员.

和非模板类的ststic数据成员一样,模板类的ststic数据成员,也应该在文件范围定义和初始化.

每个模板类都有自己的类模板和ststic数据成员副本.

例子

#include<iostream>using namespace std;template<typename T>class AA{public:static T m_a;private:};class AA1{public:static int m_a;private:};template<typename T>intAA1::m_a = 0;class AA2{public:static char m_a;private:};charAA2::m_a = 0;void main(){AA<int> a1, a2, a3;a1.m_a = 10;a2.m_a++;a3.m_a++;cout << AA<int>::m_a << endl;AA<char> b1, b2, b3;b1.m_a = 'a';b2.m_a++;b2.m_a++;cout << AA<char>::m_a << endl;//m_a应该是每一种类型的类,使用自己的m_asystem("pause");return;}

异常问题

一、为什么要有异常——WHY?

1.通过返回值表达错误

像malloc会返回0或1.

局部对象都能正确的析构

层层判断返回值,流程繁琐

例子:

#include <iostream>#include <cstdio>using namespace std;int func3 (void) {FILE* fp = fopen ("none", "r");//fopen失败会返回控指针NULL。if (! fp)return -1;// ...fclose (fp);return 0;}int func2 (void) {if (func3 () == -1)return -1;// ...return 0;}int func1 (void) {if (func2 () == -1)return -1;// ...return 0;}int main (void) {//层层判断返回值if (func1 () == -1) {cout << "执行失败!改天再见!" << endl;return -1;}// ...cout << "执行成功!恭喜恭喜!" << endl;return 0;}

2.通过setjmp/longjmp远程跳转

一步到位进入错误处理,流程简单

局部对象会失去被析构的机会

例子:

#include <iostream>#include <cstdio>#include <csetjmp> //标c的函数,跳转using namespace std;jmp_buf g_env; //jmp是专门为c量身定造的,有类的情况不适用,会跳转,因为不执行右括号,局部对象失去执行析构的机会,不会调用析构函数,会造成内存泄露class A {public:A (void) {cout << "A构造" << endl;}~A (void) {cout << "A析构" << endl;}};void func3 (void) {A a;FILE* fp = fopen ("none", "r");if (! fp)longjmp (g_env, -1); //(没有定义类的时候)这个时候是的g_env变为-1,但是不在这返回,在main函数的setjmp处返回// ...fclose (fp);}void func2 (void) {A a;func3 ();// ...}void func1 (void) {A a;func2 ();// ...}int main (void) {if (setjmp (g_env) == -1) { //(没有定义类的时候)第一次到这,genv是0,所以执行下面的func1(),执行了后在fun3中的longjmp处在缓冲区使得g_env变为1,并在这使g_env返回cout << "执行失败!改天再见!" << endl;return -1;}func1 ();// ...cout << "执行成功!恭喜恭喜!" << endl;return 0;}

———————————————————————

3.异常处理

局部对象都能正确的析构

一步到位进入错误处理,流程简单

———————————————————————

二、异常的语法——WHAT?

1.异常的抛出

throw 异常对象;

异常对象可以是基本类型的变量,也可以是类类型的对象。

当程序执行错误分支时抛出异常。

2.异常的捕获

try {

可能抛出异常的语句块;

}

catch (异常类型1 异常对象1) {

处理异常类型1的语句块;

}

catch (异常类型2 异常对象2) {

处理异常类型2的语句块;

}

catch (…) {

处理其它类型异常的语句块;

}

异常处理的流程,始终沿着函数调用的逆序,依次执行右花括号,直到try的右花括号,保证所有的局部对象都能被正确地析构,然会根据异常对象的类型,匹配相应的catch分支,进行有针对性的错误处理。

例子:#include <iostream>#include <cstdio>using namespace std;class A {public:A (void) {cout << "A构造" << endl;}~A (void) {cout << "A析构" << endl;}};void func3 (void) {A a;FILE* fp = fopen ("none", "r");if (! fp) { //如果不发生异常,不执行throw,直接执行throw后面的语句cout << "throw前" << endl;throw -1; //如果有异常,throw之后的语句不执行,直接右括号cout << "throw后" << endl;}cout << "文件打开成功!" << endl;// ...fclose (fp);}void func2 (void) {A a;cout << "func3()前" << endl;func3 (); //如果有异常,则直接右括号cout << "func3()后" << endl;// ...}void func1 (void) {A a;cout << "func2()前" << endl;func2 (); //有异常,直接右括号cout << "func2()后" << endl;// ...}int main (void) {try {cout << "func1()前" << endl;func1 (); //之后进入func1,先创建a,执行构造,再进入func2,又创建a,执行构造,再进入func3,又创建a,执行构造,然后执行throw,抛出-1;结束func3,释放func3中的a,调用析构,然后func2结束,释放func2的a,调用析构,然后func1结束,释放func1的a,调用析构。然后直接到try的右花括号,然后执行异常处理,根据异常对象的类型匹配相应的catch,这里是“执行失败”。cout << "func1()后" << endl;}catch (int ex) {if (ex == -1) {cout << "执行失败!改天再见!" << endl;return -1;}}// ...cout << "执行成功!恭喜恭喜!" << endl;return 0;}
    推荐阅读
  • 形成酸雨的主要气体是什么(形成酸雨的主要气体)

    以下内容大家不妨参考一二希望能帮到您!形成酸雨的主要气体是什么酸雨是指PH小于5.6的雨雪或其他形式的降水,形成的主要气体有二氧化硫、三氧化硫、硫化氢、二氧化氮。酸雨主要是人为的向大气中排放大量酸性物质所造成的。酸雨又分硝酸型酸雨和硫酸型酸雨。

  • 木棉花的花语是什么(木棉花的意义)

    接下来我们就一起去了解一下吧!珍惜眼前的幸福,珍惜身边的人给他们快乐与幸福。它的花期通常在3月或者4月份,在这一段时间盛开,而传说中四月的第十一天,是木棉花盛开的日子,所以4月11被定为木棉花的日子。

  • 炒凉皮不碎技巧(炒凉皮不碎有什么技巧)

    以下内容大家不妨参考一二希望能帮到您!炒凉皮不碎技巧炒凉皮不碎技巧:就是在做凉皮时不能炒太久,变软会失去筋度。胡萝卜切丝,蒜薹切段,葱切花,猪肉切丝,大蒜拍扁。成品凉皮一张张卷起切粗条,抖散备用。生抽,白糖,盐,鸡精,醋,胡椒粉调成汁备用。热锅倒适量食用油烧热加入大蒜,肉丝翻炒至金黄,加入胡萝卜丝和蒜薹炒熟,凉皮翻炒均匀后随即淋入调好的汁儿翻炒均匀。

  • 近几年灭绝的鱼(瞭望在长江源寻鱼)

    长江被誉为我国淡水渔业的摇篮、鱼类基因的宝库。据青海省渔业部门统计,长江流域青海段分布有土著鱼类21种。因此,严格意义上长江源的关键鱼类指的是裂腹鱼中的小头裸裂尻鱼。2019年,李伟带领团队参加长江源科考时,将小头裸裂尻鱼列为长江源鱼类研究的代表对象。2019年4月,科考小组五个人,两台车,开始了沿河寻觅之旅。“全球平均气温上升已是科学界的共识,位于青藏高原的长江源是全球气候变化的敏感区。”科考发现,江源地区

  • 鹧鸪在什么时候季节鸣叫(鹧鸪的孵化期有多长)

    鹧鸪在什么时候季节鸣叫鹧鸪一般会在繁殖季节鸣叫,繁殖期为3-6月,3-4月间开始求偶交配。求偶期间鸣叫更为频繁,常在山岩、树桩、灌木或乔木枝上鸣叫,尤以黎明和黄昏时更甚,往往是一鸟先鸣叫,其他雄鸟一起跟随,此起彼伏。鹧鸪的孵化期在21天左右,雏鸟出壳后不久即可跟随亲鸟活动。鹧鸪的繁殖期为每年的3-6月,3-4月间开始求偶交配,每窝产卵3-6枚,多时可达8枚,卵为椭圆形或梨形,颜色为淡皮黄色至黄褐色。

  • 秋天的诗词(这些都是关于秋天的诗句)

    迢迢新秋夕,亭亭月将圆《戊申岁六月中遇火》,今天小编就来说说关于秋天的诗词?《戊申岁六月中遇火》自古逢秋悲寂寥,我言秋日胜春朝。《秋词》是处红衰翠减,苒苒物华休。惟有长江水,无语东流。宋·柳永《八声甘州》落时西风时候,人共青山都瘦。《昭君怨》雨色秋来寒,风严清江爽。《酬裴侍御对雨感时见赠》秋声万户竹,寒色五陵松。唐·李颀《望秦川》秋色无远近,出门尽寒山。宋·苏轼《九日次韵王巩》

  • 广州有几种车牌(广州车牌你有吗)

    在广州的普通上班族,有房贷还想拥有一辆车,已经不容易了。但有车想让个广州牌,那更是难上加难,再加之限行,参与摇号,竞价的人是越来越多,那中标的机会更是渺茫了!截止日期是8日24时止。9月拟配置的中小客车增量指标共16313个,是这样分配的:1.以摇号方式向单位和个人配置节能车增量指标7285个,其中,单位指标100个,个人指标7185个。

  • qq注销账号有哪几个步骤(QQ将开注销帐号功能)

    1999年2月10日,一个名为OICQ、只有几百K的软件正式上线。当时,腾讯方面表示,这是QQ团队对帐号注销功能的灰度测试。网友截图出于安全考虑,也有网友表示支持有人说,QQ不推出注销服务有自己的考虑,这是为了防止用户QQ密码被他人知道后恶意注销,给用户带来无法挽回的损失。腾讯2018年第三季度财报显示,QQ智能终端月活跃账户同比增长6.9%至6.979亿。

  • 高跟鞋不合脚怎么办(穿高跟鞋不合脚怎么办)

    4、合理利用袜子,如果不喜欢垫各种鞋垫的朋友,可以穿一双船袜,再穿高跟鞋,那样既不影响穿着效果,也不影响美观,也是比较简单和实用的方法。

  • 年四旺名字打分104分 年四旺事迹

    文章目录:一、年四旺相关名字打分113二、年四旺相关名字评分115三、年四旺相关名字推荐四、年四旺相关名字大全五、其他人还看了一、年四旺相关名字打分113年灯石志明年橘纪红兵武尊道后书法孔多塞年贷款孙敬媛年立秋里蓝业珍冯景华年见朱诗词林于思冯桂年粤日林格孟昭毅年家薛邑马布鱼鲁初雪苏沫沫卜庆中年上年掌柜秦源达刘登龙严学锋国韵酒年线高成江裘梦年维泗红沙日年周王克斌王翔千毛淑红龙威信李万和年神范小慧王大