C++学习笔记(十九) 拷贝操作符函数 stack类的定义

学习要点:

1 学习这个stack类的定义和使用。

2 拷贝操作符函数 = ,和什么时候需要重写拷贝操作符函数。


3 切记不可以用memcpy来对string数组进行拷贝,因为string对象中的字符串是存放在堆中,memcpy会导致浅拷贝,引起多次释放的问题.



#include <iostream>
using namespace std;
typedef string T;
typedef unsigned int unit;

class Stack
{	
	T *mem;//string 类型指针 使用new 来初始化
	unit max;
	unit len;
public:
	Stack(unit n):mem(new T[n]), max(n), len(0) {}
	//拷贝构造函数 创建空间  max和拷贝的空间一样大
	Stack(Stack &s):max(s.max),len(0),mem(new T[s.max])
	{	
	}
	
	~Stack(){delete[] mem;}
	
	unit max_size() const {return max;}
	unit size() const{return len;}
	Stack& push(const T& e)
	{
		if(len >= max) throw 1;
		else mem[len++] = e;
		return *this;
	}
	
	T pop(T& e)
	{
		if(len ==0 ) throw 0;
		return mem[--len];
	}
	
	void print() const 
	{
		for(int i = 0; i< len; i++)
		{
			cout << mem[i] << "|";
		}
		cout   << endl;
	}
	
	
	//复制操作符号 删掉以前到数据  复制新的进来
	Stack& operator=(const Stack& s)
	{
			if(this == &s) return *this; //考虑自己给自己赋值的情况 这种情况在交换两个数中可能出现

			delete[] mem; //删掉原来的
			string *temp  = new T[s.max];
			len = s.len;
			for(int i =0; i< len;i++)
			{
				mem[i] = s.mem[i];
			}
		return *this;
	}
	
};

int main()
{
	Stack s1(5);
	//s1.push(1);
	//要想这样 必须push()的返回值为Stack对象引用类型的。
	s1.push("hello").push("good morning").push("早安");
	s1.print();
	
	// 谨防浅拷贝   Stack s2(s1); 重复释放错误 提示:段错误 (核心已转储)
	//所以重写了拷贝构造函数 给自己的mem分配空间
	Stack s2(s1);
	s2.print();
	s2.push("杨强").push("芙蓉");
	s2.print();
	// 复制函数 也要谨防浅拷贝
	//
	s1 = s2;
	cout << "s1 = s2之后 print" <<endl;
	s1.print();
	//如果你的程序所有的属于已完成。但弹出了 这一般是析构函数的问题。 
	//提示了两次释放
	/*
	glibc detected *** ./a.out: double free or corruption (fasttop): 0x0809e078 ***
	======= Backtrace: =========
	/lib/libc.so.6(+0x6c501)[0x17c501]
/	lib/libc.so.6(+0x6dd70)[0x17dd70]
	*/
}
/*
总结:
一般有指针成员指向动态内存的时候,默认的拷贝构造函数和赋值函数都会简单地将指针复制一份,
这会带来多次释放的问题。
所以有指针成员指向动态内存的时候需要
自己写 拷贝构造函数  赋值函数(operator=) 析构函数
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值