一、模板,函数模板
2024.08.06
1.模板:
(1)概念:模板是实现代码重用机制的一种工具。
(2)作用:可以把类型定义为参数,实现类型参数化,从而实现代码重用,大幅度提高程序设计效率。
(3)分类:分为函数模板和类模板,分别允许用户构造模板函数和模板类。
2.函数模板:
(1)概念:建立一个有虚拟类型的通用函数。调用时根据实参类型取代虚拟类型,实现不同类型函数的功能。
(2)声明:
template <typename 自定义的虚拟类型参数>
返回类型 函数名(模板形参表(要带上类型))
{ 函数体 }
(3)使用:
eg1:
template <typename AT>
int i;//错误:注意事项c.此处不能插入别的语句。
AT max(AT x,AT y)
{
return (x>y)?x:y;
}
eg2:
template <typename type1,typename type2>
void show(type1 x,type2 y)
{
cout<<x<<’and’<<y<<endl;
}
(4)注意事项:
a.使用函数模板时,必须将类型参数实例化。
b.函数模板中允许使用多个类型参数,但每个前面都要有typename(或class,一般常用typename)。
(eg:template <typename AT1,typename AT2>)
c.在template语句与函数模板定义语句之间不能插入别的语句。
d.函数模板可以重载;也可与同名的非模板函数重载(此时调用时,先找参数完全匹配的非模板函数,再找函数模板。恰当运用这种机制,可以很好地处理一般与特殊的关系)。
二、类模板
2024.08.07
1.类模板:
(1)声明:a.与函数模板格式类似,必须以关键字template开始:
template <typename 类型参数>
class 类名{
类成员声明
};
b.在类模板体外定义的成员函数的一般形式如下:
template <typename 类型参数>
函数类型 类名<类型参数>::成员函数名(形参表)
{ … };
eg:
template <typename T>
T Three<T>::sum()
{ return x+y; }
(2)注意事项:
a.使用类模板时,必须将类型参数实例化,且前面要加typename。
b.需要在成员函数定义之前进行模板声明。
c.在类模板体外定义构造函数时,不需要添加返回类型:
三、const修饰符,void型指针,自引用指针this,new和delete运算符
2024.08.08
1.const修饰符:
(1)定义:C++中更灵活,更安全的方式定义常量。
(2)作用:与#define相似,但消除了#define的不安全性。
(3)组合:const可与指针一起使用,组合情况较复杂,归纳为3种:
a.指向常量的指针:const char* p (地址可改,内容不可改)
b.常指针:char* const p (内容可改,地址不可改)
c.指向常量的常指针:const char* const p (均不可改)
(4)自己的理解:
a. p:指针变量本身,存储的是一个内存地址。
b. *p:表示指针所指内存位置处存储的值(即内容)。
(5)说明:
a.常量一旦被建立,在程序的任何地方都不能再更改。
b.与#define不同,const定义的常量可以有自己的数据类型。
c.如果const定义的是整型常量,关键字int可省略。
eg:const int num=1;等价于const num=1;
d.函数参数也可用const 修饰,保证实参不被改变。
(大多数C++编译器对具有const参数的函数进行更好的代码优化)
eg:希望通过函数Max( )求整型数组a[200]中的最大值:
函数原型:int Max(const int* ptr)
调用时格式可以是:Max(a);
目的:确保原数组数据不被破坏,即对其操作只读不写。
2.void型指针:
(1)void通常表示无值。
(2)void型指针:通用型指针,表示不确定的类型,可接受任何类型的指针的赋值。但对已获值的void型指针再操作时,必须进行显示类型转换,否则会出错。
(3)注意:
a.不能声明void 类型的变量。(与空间占用内存有关)
b.可以声明void类型的指针。(与类型无关)
3.自引用指针this:
(1)定义:在 C++ 中,每个对象都有一个隐藏的指针 this,它指向对象本身。当对象调用成员函数时,this 指针会被自动传递给成员函数,this指针的值是该对象的起始地址。
(2)使用:有显示使用和隐式使用两种:
显示使用是用指针的“箭头运算符”表示出来。
(3)作用:
a.区分同名变量(在显示使用中也有提及):
b.返回对象自身的使用(显示使用中也提及到可作为返回值):
但要注意区别: this指针是调用该成员函数的对象的地址;
*this指针是调用该成员函数的对象。
c.传递对象:
(4)补充:之前不太明确成员变量和局部变量是什么:
(5)this 指针的特点:
a. 它只能在类的非静态成员函数中使用,静态成员函数没有 this 指针,因为静态成员函数不与特定的对象相关联。
b. this 指针是一个常量指针,其值在对象的生命周期内不能被修改。
eg: copy(Sample& xy)
{ if(this==&xy) return;
*this=xy; //注:此处不可写成this=&z.因为this是常指针
}
(注:this是常指针,不可修改,但可引用)
4.new和delete运算符
(1)引入:
a.程序运行时,计算机的内存被分为4个区:程序代码区、全程数据区、栈和堆。其中,堆可由用户分配和释放。
b.C语言使用函数malloc()和free()等进行动态内存管理(分配与释放)。
c.C++提供运算符new和delete来做同样的工作,更方便灵活。
(2)使用:
a. 指针变量名=new 类型;eg: int *p; p=new int;
(new从称为堆的自由存储区中分配一块与类型字节数相适应的内存空间,并将该内存的首地址存于指针变量中)
b.delete 指针变量名; eg: delete p;
(delete用于释放运算符new分配的内存空间)
(3)优点:
a.new可自动计算所要分配的空间,不用再用sizeof( ),减少错误发生。
b.new可自动返回正确的指针类型,不必再进行强制类型转换。
(4)说明:
a.用new分配的空间,使用结束后该用也只能用delete显示释放,否则因不能回收变成死空间。
b.使用new时,如果没有足够内存满足空间分配要求,new将返回空指针(NULL)。因此,通常要对内存的动态分配是否成功进行检查。
c.可以用new为数组动态分配内存空间,需要在类名后加上数组大小,但必须提供所有维的大小。
语法形式: 指针变量名=new 类型名[下标表达式];
eg:int *pi=new int[2][3][4];
d.释放动态分配的数组存储区时,可用delete运算符,指针变量名前只需要一对 方括号符,无须指出数组的维数和大小。
语法形式: delete [ ]指针变量名;
eg: delete [ ]pi;
e.new 可在为简单变量分配内存空间的同时,进行初始化。
(注:new不能对动态分配的数组存储区进行初始化。)
语法形式: 指针变量名=new 类型名(初值);
eg: int *p=new int (99);