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

例子1复数类—-所有函数写的类的内部 #include<iostream> usingnamespacestd; template<typenameT> classComplex { firendostream&operator<<(ostream&out,Complex&c3) { cout<<"a:"<<"…

例子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;
	}
	Complex  operator+(Complex &c2)
	{
		Complex tmp(a + c2.a, b + c2.b);
		return tmp;
	}
	void printComplex()
	{

		cout << \"a:\" << a << \"b:\" << b << endl;
     }
	
private:
	T  a;
	T  b;
};
//运算符重载的正规写法,重载<<  >>只能用友员函数,其他运算符重载,都要写成成员函数,不要滥用友员函数

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 Complex  MySub<<(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)
		Complex  operator+(Complex &c2)
		void printComplex();

private:
	T  a;
	T  b;
};
template<typename T>//构造函数的实现,写在了类的外部
Complex<T>::Complex(T a,T b)
{
	this->a = a;
	this->b = b;
}
template<typename T>
void  Complex::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>
int  AA1::m_a = 0;

class AA2
{
public:
	static char m_a;
private:

};
char  AA2::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_a
	system(\"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;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年5月12日 下午6:01
下一篇 2022年5月12日 下午6:02

相关推荐

  • 工兵铲哪个牌子好用(质量最好的工兵铲)

    这年头,大家不知道有没有感受到,越来越多的年轻人都开始喜欢往农村、往深山里跑。哪怕是没有时间,在网上看看李子柒种种辣椒、看看野食小哥在户外找食材做饭,都是件小意思的事情。 小编内心蠢蠢欲动了好久,趁着小长假来临之际,准备来个户外之旅。为了这次户外活动,光是工具,小编费了好大劲,总算是在小米有品上找到满意的了,真是太适合我们这种90后年轻人啦! 开箱 包装做的相当简约,只有一把铲子的简笔画在正中央,…

    2022年10月26日
    1210
  • 手机照片误删怎么恢复,具体操作步骤分享给大家

    在手机相册里的照片误删了怎么恢复这个问题上,不管是我们的苹果用户还是安卓用户,都十分关注,手机相册里的照片误删了又没有找到怎么恢复的方法怎么办呢?本篇文章将为我们所有的手机用户们分享关于手机相册里的照片误删了怎么恢复的教程,通过专业的手机数据恢复软件进行照片恢复的,只要选对数据恢复软件,并且丢失照片没有被覆盖,用户就可以自行解决手机相册里的照片误删怎么恢复的问题。 一、苹果手机相册里的照片误删怎么…

    2022年7月14日
    550
  • 增值税发票作废如何处理,税务局开专票作废及退税流程

    之前给大家介绍过增值税一般发票的作废处理办法,今天为大家介绍增值税普通发票想要作废的话应该如何处理呢?一起来看! 作废增值税普通发票的前提条件是什么呢?根据规定: 1、收到退回的发票联和抵扣联时间没有超过销售那方开票当月的 2、销售的那一方没有抄税并没有记账的 3、购货方没有认证或者是认证的结果是“纳税人识别号认证不符”、“普通发票代码、号码认证不符”的。 一、增值税普通发票如果是当月作废的该怎么…

    2022年6月12日
    4040
  • 刷微信指数有哪些方法,微信指数提升方法

    昨日晚间,微信官方悄然推出了“微信指数”功能,腾讯方面定义其为微信官方提供的基于微信大数据分析的移动端指数。 那么,微信指数如何使用呢?我们体验过后,主要有以下几个步骤: 1、打开微信。在顶部搜索框内输入“微信指数”四个关键字。 2、点击“微信指数”进入主页面,然后再点击微信指数里面的搜索框,输入自己想要的关键词得出的数据。 3、目前微信指数只支持7日、30日、90日内的三个阶段的数据,最早只能搜…

    2022年8月6日
    1990
  • kitchenaid厨师机哪款好(最实用性价比超高的一款厨师机)

    KitchenAid,顾名思义就是你的厨房帮手。其产品主要目的是帮你完成任何费劲儿的步骤,尤其是厨师机。 为了庆祝100年诞辰,KitchenAid推出迷雾蓝配色的限量版厨师机。迷雾蓝机身搭配白色搅拌碗,看着挺清爽的。 机子本身和KitchenAid经典的5夸脱Artisan是一样的,配件包括三个搅拌头和一个导流槽。 比如说在机子上安装上打蛋网,它就能打发蛋清和淡奶油,制作各种西点;搅拌桨主要用来…

    2022年9月22日
    500
  • 市场营销是什么,市场营销概念及其含义介绍

    什么是市场营销?我们要想真正地去理解市场营销,关键是要学会洞察4P和4C背后的逻辑、角色及它们之间的联系。 相信大多数营销人都有以下我这样类似的经历和困惑: 在我之前就职的一家口腔医院,当医生介绍专业知识时,财务介绍资金计划时,人事部介绍公司愿景时,大家都很安静,偶尔才会有人举手谦虚谨慎的提一两个问题。 等讲到公司的市场营销时,整个气氛突然活跃了起来,无论是医生还是财务,每一个人都踊跃参与讨论,每…

    2022年5月19日
    640
  • 关键词密度计算方法有哪些,网页关键词密度最佳值

    在网站的内容优化中,网站的关键词的密度设置其实在优化中也是至关重要的!所以关键词密度的设置,关键词密度的疏密在内容优化中都是至关重要的!今天我们就来看看关键词的密度设置! 1. 很多人关键词密度很低,但是排名做得很好,就会容易产生一个关键词密度控制不控制无所谓的想法,这种想法比较绝对,任何一个因素都会影响关键词在搜索引擎的排名,大家试想一下,如果你的关键词密度比较低,但是排名不错,内容很好,若是有…

    2022年8月28日
    440
  • 怎样做好品牌推广,品牌的市场推广计划

    一、品牌定位/创建要明确 对于品牌推广来说,品牌定位的准确与否,直接关系到推广的效果。品牌定位,就是为了结合自身的现状、优势、愿景等确定行业、市场。品牌是做什么行业,在行业中要做到什么程度,是做国内市场还是国外市场,通过什么方式去销售,产品针对的消费者是低端、中端还是高端的。做品牌定位,一定要有格局,打算为哪些人提供服务,产品满足哪些人的需求,只有满足了目标消费者的需求,并做好口碑。 二、品牌价值…

    2022年8月8日
    550
  • 什么技术最赚钱且稳定,分享三个高新又轻松的技术

    在进入社会工作以后,其实大多数年轻人都希望自己能够找到一份安稳并且能够长远发展的工作,不用担心失业,但是并不是所有年轻人都有这样的资历或者学历,他们在行业的工作几年后,便因为工作不顺心或者工资较低,所以选择了辞职,甚至因为工作能力过差被公司所辞退,那么什么职业越老越吃香,而且收入稳定呢?笔者在此也是推荐以下这三份职业,至少能够在行业中发展长远,不用担心失业,所以还是非常适合大家的。 第一、医院里的…

    2022年10月12日
    500
  • 摆地摊卖时尚女鞋,教你摆地摊如何增加人气

    每当夜幕降临,常德城区的一些地段开始热闹起来。黄色灯影下的大排档、卖鞋的、卖衣的、卖精品的地摊小贩吆喝着叫卖着…… 作为夜市经济的一部分,“地摊经济”最近十分火爆。中央文明办明确要求,不将占道经营、马路市场、流动商贩列为今年文明城市测评考核内容。这对于受疫情冲击的流动商贩来说,无疑是重大的利好。 小吃街的热闹场景。 夫妻搭档摆摊 “50元一双,谢绝还价。”在市城区水星楼商业小吃街,29岁的欧凯和妻…

    2022年8月22日
    580

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信