new与delete的用法
1、在软件开发过程中,常常需要动态地分配和撤销内存空间。在C语言中是利用库函数malloc和free来分配和撤销内存空间的。C++提供了较简便而功能较强的运算符new和delete来取代malloc和free函数。
注意: new和delete是运算符,不是函数,因此执行效率高。
2、虽然为了与C语言兼容,C++仍保留malloc和free函数,但建议用户不用malloc和free函数,而用new和delete运算符。
new运算符的例子:
new int; //开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针)
new int(100); //开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址
new char[10]; //开辟一个存放字符数组(包括10个元素)的空间,返回首元素的地址
new int[5][4]; //开辟一个存放二维整型数组(大小为5*4)的空间,返回首元素的地址
float *p=new float (3.14159); //开辟一个存放单精度数的空间,并指定该实数的初值为3.14159,将返回的该空间的地址赋给指针变量p
3、new和delete运算符使用的一般格式为:
4、用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否成功。
对象的动态建立和释放
使用类名定义的对象都是静态的,在程序运行过程中,对象所占的空间是不能随时释放的。但有时人们希望在需要用到对象时才建立对象,在不需要用该对象时就撤销它,释放它所占的内存空间以供别的数据使用。这样可提高内存空间的利用率。
C++中,可以用new运算符动态建立对象,用delete运算符撤销对象
C++还允许在执行new时,对新建立的对象进行初始化。如:
Box *pt=new Box(12,15,18);
这种写法是把上面两个语句(定义指针变量和用new建立新对象)合并为一个语句,并指定初值。这样更精炼。
面向对象模型
1、C++类对象中的成员变量和成员函数是分开存储的
普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
静态成员变量:存储于全局数据区中
成员函数 :存储于代码段中。
那么问题来了:很多对象共用一块代码?代码是如何区分具体对象的呢?
2、C++编译器对普通成员函数的内部处理 :C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
静态成员函数、成员变量属于类
静态成员函数与普通成员函数的区别:
静态成员函数不包含指向具体对象的指针( 静态成员函数内部没有 this 指针, 无法使用类的普通成员变量)
普通成员函数包含一个指向具体对象的指针
3、this指针
当数据成员和函数的形参同名时,数据成员被函数成员的形参隐藏起来,在类的成员函数中如何访问类的数据成员呢?想要解决这个问题,就需要使用this指针,this指针是指向当前对象的,或者说是当前对象的地址,this只能在一个类的成员函数中使用,通过this指针可以访问到类中的数据成员。
#include <iostream>
using namespace std;
class Clock
{
private:
//类的私有成员
int hour;
int minute;
int second;
public:
void show_timer()
{
cout << hour << ":" << minute << ":" << second << endl;
}
//void set_timer(Clock *const this, int hour, int minute, int second)隐藏this指针
void set_timer(int hour, int minute, int second) //类的成员函数参数
{
this->hour = hour; //this指针访问类中的数据成员
this->minute= minute;
this->second= second;
}
};
int main()
{
Clock a;
a.set_timer(11,11,11);
a.show_timer();
a.set_timer(12,34,56);
a.show_timer();
return 0;
}
程序执行结果:
11:11:11
12:34:56
4、const修饰成员函数
#include <iostream>
using namespace std;
class Test
{
private:
int m_a;
int m_b;
public:
Test(int a, int b)
{
m_a = a; //比较使用this指针
m_b = b;
}
// const 在类的内部使用
void print () const // void print (const Test *const this)
{
printf ("a = %d, b = %d\n", this->a, this->b);
}
};
int main()
{
Test t(1,2);
t.print();
return 0;
}
5、全局函数与成员函数
1)把全局函数转化成成员函数,通过this指针隐藏左操作数
Test add(Test &t1, Test &t2)===>Test add(Test &t2)
2)把成员函数转换成全局函数,多了一个参数
void printAB()===>void printAB(Test *this)
3)函数返回元素和返回引用
Test& add(Test &t2) //*this //函数返回引用
{
this->a = this->a + t2.getA();
this->b = this->b + t2.getB();
return this; //操作让this指针回到元素状态
}
Test add2(Test &t2) //*this //函数返回元素
{
//t3是局部变量
Test t3(this->a+t2.getA(), this->b + t2.getB()) ;
return t3;
}