C/C++基础----类(2)

C++动态空间

  在C++ 开辟空间,可以使用关键字new,释放空间所用的方法是delete。与C中的malloc类似,在C++中动态开辟的空间依旧是在堆空间上需要手动释放。下面的例子说明了这一过程。

#include<stdio.h>
#include<iostream>

class Rect
{
private:
	int pos_x;
	int pos_y;
	int width;
	int height;
	char *p;

public:
	Rect(int _w, int _h)
	{
		width = _w;
		height = _h;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	Rect()
	{
		width = 5;
		height = 5;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	~Rect()
	{
		free(p);
		printf("析构函数被调用,释放地址%p\n\n", p);
	}

	void set_para(int _w, int _h)
	{
		width = _w;
		height = _h;
	}

	void show_info()
	{
		printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
	}

};

int main()
{
	{
		Rect R1;
		//动态创建对象
		Rect *R3 = new Rect;
		//手动释放
		delete R3;
	}

	Rect R2(2, 3);
	getchar();
	return 0;
}

  从上面的代码可以看出,每创建一个对象,都会在对空间上动态开辟一个空间用来存放指针p;R3的生命周期结束前需要将其手动释放,否则会发生内存的泄露。

在这里插入图片描述

  对于开辟出来的数组类型的动态空间,在释放时,需要指定释放的空间是数组类型的。

#include<stdio.h>
#include<iostream>

class Rect
{
private:
	int pos_x;
	int pos_y;
	int width;
	int height;
	char *p;

public:
	Rect(int _w, int _h)
	{
		width = _w;
		height = _h;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	Rect()
	{
		width = 5;
		height = 5;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	~Rect()
	{
		free(p);
		printf("析构函数被调用,释放地址%p\n\n", p);
	}

	void set_para(int _w, int _h)
	{
		width = _w;
		height = _h;
	}

	void show_info()
	{
		printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
	}

};

int main()
{
	{
		Rect R1;
		Rect *R3 = new Rect[10];
		delete[] R3;
	}

	Rect R2(2, 3);
	getchar();
	return 0;
}

在这里插入图片描述

拷贝构造函数

  拷贝构造和默认构造函数类似,在创建新对象时会自动调用。拷贝构造函数中含有拷贝过程,将一个对象中的成员变量赋值给新对象中的成员,但是有时候需要深度拷贝时,需要注意对象的生存周期。拷贝函数的名字和类名相同,拷贝过程中,需要传递一个变量的引用。
  调用拷贝构造函数时,有如下三种情况:

  1. 由显示或隐式的方法,使用一个对象来创建一个新对象时
  2. 函数传递参数时,传递的参数是一个对象时,接收参数时调用拷贝构造函数
  3. 函数返回值是一个对象,并且用这个返回值创建了一个新的对象使,会调用构造函数
#include<stdio.h>
#include<iostream>

class Rect
{
private:
	int pos_x;
	int pos_y;
	int width;
	int height;
	char *p;

public:
	Rect(int _w, int _h)
	{
		width = _w;
		height = _h;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	Rect()
	{
		width = 5;
		height = 5;
		pos_x = 0;
		pos_y = 0;
		p = (char *)malloc(sizeof("RECT 构建由默认构造函数完成"));
		memcpy(p, "RECT 构建由默认构造函数完成", sizeof("RECT 构建由默认构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	Rect( Rect & _r)
	{
		pos_x = _r.pos_x;
		pos_y = _r.pos_y;
		width = _r.width;
		height = _r.height;
		p = (char *)malloc(sizeof("RECT 构建由拷贝构造函数完成"));
		memcpy(p, "RECT 构建由拷贝构造函数完成", sizeof("RECT 构建由拷贝构造函数完成"));
		printf("%s ;地址%p \n\n", p, p);
	}

	~Rect()
	{
		free(p);
		printf("析构函数被调用,释放地址%p\n\n", p);
	}

	void set_para(int _w, int _h)
	{
		width = _w;
		height = _h;
	}

	void show_info()
	{
		printf("width = %d; height = %d; length = %d\n", width, height, 2 * (width + height));
	}

};

void test(Rect r)
{
	r.show_info();
}

Rect test_a(int w, int h)
{
	Rect R1(1, 5);
	return R1;
}

int main()
{
	{
		//创建对象
		Rect R1;
		//拷贝方式创建对象
		Rect R3 = R1;
		//传递参数是对象时,调用拷贝构造函数
		test(R3);
		//接收返回值是对象时,调用拷贝构造函数
		Rect R4 = test_a(1, 5);
	}

	Rect R2(2, 3);
	getchar();
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值