C++面向对象——构造函数和析构函数、深拷贝和浅拷贝

本文详细讲解了C++中的构造函数和析构函数,阐述了它们在对象生命周期中的作用,以及为何不能在对象中使用memcpy和realloc。此外,文章还探讨了深拷贝和浅拷贝的概念,强调了当对象包含指针成员时,浅拷贝可能导致的问题,并给出了避免问题的方法,包括自定义拷贝构造函数和赋值操作符重载。最后,通过String类和循环队列的例子进一步解释了深浅拷贝的重要性。
摘要由CSDN通过智能技术生成

构造函数和析构函数

根据OOP思想 实现一个顺序栈:

class SeqStack
{
   
public:
	void init(int size = 10)//初始化
	{
   
		_pstack = new int[size];
		_top = -1;
		_size = size;
	}
	void release()//释放对象成员变量占用的外部堆内存(外部资源)
	{
   
		delete[]_pstack;//释放数组内存
		_pstack = nullptr;//防止野指针
	}
	void push(int val)
	{
   
		if (full())
		{
   
			resize();
		}
		_pstack[++_top] = val;
	}
	void pop()
	{
   
		if (empty())
			return;
		--_top;
	}
	int top()
	{
   
		return _pstack[_top];
	}
	bool empty() {
    return _top == -1; }
	bool full() {
    return _top == _size - 1; }
private:
	int *_pstack;//动态开辟数组,存储顺序栈的元素
	int _top;//栈顶元素的位置
	int _size;//栈的总大小

	void resize()//不是给用户用的,防止用户使用,所以定义为私有
	{
   
		int *tmp = new int[_size * 2];
		for (int i = 0; i < _size; i++)
		{
   
			tmp[i] = _pstack[i];
		}
		/*
		为什么不用memcpy(tmp, _pstack, sizeof(_size));realloc???
		memcpy,realloc如果是拷贝数据时,可以用,但是如果拷贝对象就不一定正确了
		*/
		delete[]_pstack;
		_pstack = tmp;
		_size *= 2;
	}
};
int main()//
{
   
	SeqStack s1;
	s1.init(5);//初始化——手动调用
	for (int i = 0; i < 15; ++i)
	{
   
		s1.push(rand() % 100);//给这个栈添加上15个元素
	}	

	while (!s1.empty())
	{
   
		cout << s1.top() << " ";
		s1.pop();
	}

	s1.release();//释放对象成员变量占用的外部堆内存(外部资源)——手动调用
	return 0;
}

其中热resize函数之所以定义在私有成员里,主要目的就是,防止用户使用,所以定义为私有。因为如果用户可以任意使用的话可能会造成间接更改私有成员变量。
同时,里面为什么用for循环?为什么不用memcpy()或者realloc()?
答:memcpy和realloc这里涉及的都是内存的拷贝,在对象里面并不适合。因为对象里面可能存在指针会调用外部内存,单纯的内存拷贝,会造成不同指针指向同一块内存。但是在这里其实是没有问题的,因为数组是在栈上,栈里面的内容存的都是整型,可以做内存的拷贝。

除此之外,上面的代码还存在一些问题,release()调用函数虽然在堆上new的资源被释放了,但是手动调用这个在使用中容易遗忘!!!!!

所以为了解决这个问题,就引入构造函数(自动进行初始化)和析构函数(自动释放资源),
构造函数和析构函数:
1 函数的名字和类名一样;
2 没有返回值;
3 代替了对象的成员变量的初始化操作; 对象不使用了,出作用域之前 把对象占用的外部资源都进行释放。(此时的 指针指向了初始化时候开辟的堆上的一块资源)

class SeqStack
{
   
public:
	SeqStack(int size = 10)//构造函数,可以带参数,因此可以提供多个构造函数,形成函数重载
	{
   
		cout << this << " SeqStack() " << endl;
		_pstack = new int[size];
		_top = -1;
		_size = size;
	}
	~SeqStack()//析构函数,是不带参数的,所以析构函数只能有一个
	{
   
		cout << this << " ~SeqStack() " << endl;
		delete[]_pstack;
		_pstack = nullptr;
	}
	void push
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值