Day13(下).new和delete//static专题//类内存模型分析



回忆一下类的相关知识:
看一段代码:
#include "iostream"
using namespace std;

class Test
{
private:
	int m_a;
	int m_b;
	int m_c;
public:
	Test(int a, int b)
	{
		m_a = a;
		m_b = b;
		Test(a, b, 10);
	}
	Test(int a, int b, int c)
	{
		this->m_a = a;
		this->m_b = b;
		this->m_c = c;
	}

	~Test()
	{
		cout << m_a << "," << m_b << endl;
	}

public:
	int getnum()
	{
		return m_c;
	}
};

void main()
{
	Test t1(1, 2);
	cout << t1.getnum() << endl;

	system("pause");
}
仔细研究其中一段代码,我们先截取出来:
	Test(int a, int b)
	{
		m_a = a;
		m_b = b;
		Test(a, b, 10);
	}
	Test(int a, int b, int c)
	{
		m_a = a;
		m_b = b;
		m_c = c;
	}
当执行到
Test(a, b, 10);
时,会调用三个参数的Test构造函数,按照一般的函数的话,应该没有问题,但是这里是一个构造函数,是如何执行的呢????????????
当三个参数的构造函数执行完以后,这时候返回的是一个匿名对象,当从三个参数的构造函数返回以后,匿名对象就会调用析构函数,这时候m_c的值就会是一个垃圾值。 这里需要说明的是,如果创建的匿名对象没有变量来接他,就会立即调用析构函数进行释放。

new和delete操作符专题

new运算符动态分配堆内存
使用形式:
  指针变量 = new 类型(常量);
               指针变量 = new 类型[表达式];
作用:从堆分配一块“类型”大小的存储空间,返回首地址
其中:"常量"是初始化值,可缺省
            创建数组对象时,不能为对象指定初始值
delete运算符释放已分配的内存空间
使用形式:  delete 指针变量;
               delete[] 指针变量;
其中,“指针变量”必须是new返回的指针
代码:
#include "iostream"
using namespace std;
//1.new/delete 作用手工分配堆内存  malloc/free
//2.new/delete int基础类型
//3.new/delete 数组
//4.new/delete类
void main()
{
	cout << "*****************" << endl;
	int *p1 = new int;
	*p1 = 10;//初始化数值为10
	cout << *p1 << endl;
	delete p1;

	cout << "*****************" << endl;
	int *p2 = new int(10);//初始化数值为10
	*p2 = 10;
	cout << *p2 << endl;
	delete p2;

	cout << "*****************" << endl;
	int *p3 = new int[10];//初始化大小为10
	for (int i = 0; i < 10; i++)
	{
		p3[i] = i + 1;
		cout << p3[i] << endl;
	}
	delete[] p3;
	cout << "*****************" << endl;

	system("pause");
}

new、delete和malloc、free的区别
#include "iostream"
using namespace std;
//1.new/delete 作用手工分配堆内存  malloc/free
//2.new/delete int基础类型
//3.new/delete 数组
//4.new/delete类
class Test1
{
private:
	int m_a;
	int m_b;
public:
	Test1(int a, int b)
	{
		m_a = a;
		m_b = b;
		cout << "构造执行" << endl;
	}
	~Test1()
	{
		cout << "析构执行" << endl;
	}
};
//C++中的new能自动调用构造函数,delete自动调用类的析构函数,malloc是不会这样的
void main3()
{	
	Test1 t1(1, 2);
	Test1 *p1 = new Test1(3, 4);
	delete p1;
}

void main()
{
	cout << "*****************" << endl;
	main3();
	cout << "*****************" << endl;
	system("pause");
}
C++中的new能自动调用构造函数,delete自动调用类的析构函数,malloc和free是不会调用构造和析构函数的。
继续引申,看二级指针做函数参数的问题:
int CreateTest1(Test1 ** p1)
{
	Test1 *tmp = new Test1(4, 5);
	*p1 = tmp;
	return 0;
}

int CreateTest1(Test1 * &p2)
{
	p2 = new Test1(6, 7);
	return 0;
}
但是有一个大问题:new delete malloc free能混用吗?
对于int等基础类型的new delete malooc free是可以混用的!!!!!!!!!
对于类而言,使用new和free,free只是释放了类Test的内存空间,但是Test里面如果有*p,p指向了内存空间,这时候free是不能调用析构函数进行这段内存空间的释放的。

但是还有一个大问题:free时能否留下一部分内存呢??看下面的代码
delete[] (p+1)
答案是否定的!!!头指针包含了其他的内容,虽然我不知道,但是老师说有,头指针就是头指针,不能从某一段内存开始释放。



static专题
static修饰的变量只会执行一次,来段代码看看:
#include "iostream"
using namespace std;

void getstatic()
{
	int a = 10;
	static int b = 20;
	return;
}
void main()
{
	getstatic();
	getstatic();

	system("pause");

}
另外;
//这个函数只能在当前的源文件里执行
static void myprintf()
{
	printf("锄禾日当午,生活真是苦");
	printf("送走C语言,来了它大叔(C++)");
}

注意下面的代码,假设有X类,定义了4个a b c d变量,有一个static yy,yy的值是在a b c d中共享的,也就是在a b c d中yy的值是一样的
class X
{
	char xx;
	static char yy;
	int X::yy = 0;
	X a, b, c, d;
};



静态数据成员的说明和初始化:
必须这样做!!!
public:
	int mem;
	static int smem;
	counter(int a)
	{
		mem = a;
	}
};
//必须在类的外面进行初始化
int counter::smem = 1;
记住一句话:static修饰的变量或函数,属于这个类,也属于具体的对象

小细节注意:
细节1:
	static int getnum()
	{
		return num;
	}
num是static的,在函数类型前面要加上static

细节2:

class counter
{
private:
	int m_a;
	static int num;
public:
	counter(int a)
	{
		m_a = a;
		num++;
	}
	static void getcount()
	{
		//getcount()函数是属于一个类的,可以先于某一个变量存在
		cout << m_a << endl;//ERROR
		//static变量是多个类明
		cout << num << endl;
	}

};
类中的函数也是属于一个类的,在这个函数体内是不能调用公共成员变量的,因为成员函数也是属于这个类,可以先于某一个变量存在,所以无法这样使用。
cout << m_a << endl;//ERROR


C++中类的内存模型分析
C++的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类。从计算机的角度,程序依然由数据段和代码段构成。
C++编译器如何管理类、对象、类和对象之间的关系的呢?
具体的说,具体对象调用类的方法,那么C++编译器是如何区分,是哪个具体的类调用这个方法的呢???

我们用内存模型解释C++的属性和方法
1) C++类对象的成员变量和成员函数是分开存储的
    成员变量:
          普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
          静态成员变量:存储于全局数据区中
    成员函数:
          存储于代码段中
class C
{
private:
	int a =0;
	int b =1;
	int c =2;
	const int d;
public:
	int getnum()
	{
		return a;
	}
};
对于const成员变量是放在全局数据区,成员函数是放在了代码区,都不占用具体的内存空间。
我们看一下C++编译器是如何处理的:


我们看一下this指针:
	Test(int a)
	{
		a = a;
	}
C++编译器其实是这样的:
	Test(this, int a)
	{
		this->a = a;
	}
谁调用Test,this就是谁!!!!

总结:
1)C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存模型仍然有效!
2)C++类中的普通成员函数都隐式包含一个指向当前对象的this指针
3)静态成员函数、成员变量属于类
4)静态成员函数与普通成员函数的区别:
        静态成员函数不包含指向具体对象的指针
        普通成员函数包含一个指向具体对象的指针

本节结束!!腰累坏了!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值