一、动态内存分配
1.第一种用法,分配一个变量:
P = new T;
T是任意类型名,P是类型为T*的指针。动态分配出一片大小为sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P。比如:
int *pn;
pn = new int;
*pn = 5;
2.第二种用法,分配一个数组:
P= new T[N];
T:任意类型名;
P:类型为T*的指针;
N:要分配的数组元素的个数,可以是整型表达式。
动态分配出一片大小为N*sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋给P。
例如:
int *pn;
int i = 5;
pn = new int[i*20];
pn[0]=20;
pn[100] =30;//编译没有问题,运行时导致数组越界,最大下标为99才对
new运算符返回值的类型都是T*。
3.用delete运算符释放动态分配的内存
用new动态分配的内存空间,一定要用delete运算符进行释放。
格式如下:
delete 指针;//该指针必须指向new出来的空间
例如:
int *p = new int;
*p = 5;
delete p;
delete p;//异常,一片空间不能被delete多次
用delete释放动态分配的数组,要加“[]”。,格式如下:
delete[] 指针;//该指针必须指向new出来的数组。
如果不加[],那么delete的空间就不会被释放完全。
二、内联函数和重载函数,函数参数缺省值
1.内联函数
函数调用是由时间开销的。如果函数本身只有几条语句,之行很快,而且执行次数较多,那么调用函数产生额外开销比较大,。为了减少函数调用的开销,引入了内联函数机制。编译器处理对内联函数的调用语句时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的语句。
内联函数的书写格式:
inline 函数返回值类型 函数名称(参数)
{
函数体;
}
2.函数重载
同java类似,不再累述,根据调用语句中的实参的个数和类型判断应该调用哪个函数。但是若实参的个数和类型一致,只是返回值类型不同,就不是重载,会报错。
3.函数参数缺省值
定义函数的时候可以让最右边的连续若干个参数有缺省值。
三、类和对象的基本概念与用法
结构化程序设计中,函数和其操作的数据结构没有直观联系。
重用:在编写某个程序时,发现其需要的某项功能,在现有的某个程序里已经有了相同或类似的实现,那么自然希望能够将那部分代码抽取出来,在新程序中使用。
在结构化程序设计中,随着程序规模的增大,由于程序大量函数、变量之间的关系错综复杂,要抽取这部分代码,会变得十分困难。
面向对象的程序设计具有:抽象、封装、继承和多态四个基本特点。
例程:
class CRectangle
{
public:
int w,h;
int Area(){
return w*h;
}
int Perimeter(){
return 2*(w+h);
}
void Init(intw_,inth_){
w = w_;
h = h_;
}
};//必须要有分号
在主程序中使用:
int main()
{
int w,h;
CRectangle r;//新建一个类
cin>>w>>h;
r.Init(w,j);;//初始化赋值
cout<<r.Area()<<endl<<r.Perimeter();
return 0;
}
和结构变量一样,对象所占用的内存空间的大小,等于所有成员变量(不包括成员函数)的大小之和。
每个对象各有自己的存储空间,一个对象的某个成员变量被改变了不会影响另一个对象的成员变量。
和结构变量一样,对象之间可以用“=”进行赋值,但不可以运用别的运算符号,除非重载。
第二种使用类的成员变量和成员函数的方法:
指针->成员名。
第一种类似于Java,不说了。
用法3:引用名.成员名
CRectangle r2;
CRectangle & rr =r2;
rr.w=5;
rr.Init(5,4);//rr的值边了,r2的值也变