⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmtrace.cpp

📁 学习类的
💻 CPP
字号:
// mmtrace.cpp: implementation of the mmtrace class.
//
//////////////////////////////////////////////////////////////////////

#include "mmtrace.h"

#include "memoryCheck.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

class tformat
{
	int depth;
public:
	tformat():depth(0)
	{
	}
	void operator++()
	{
		depth +=2;
	}
	void operator--()
	{
		depth -=2;
	}
	void operator++(int)
	{
		operator++();
	}
	void operator--(int)
	{
		operator--();
	}
	void indent()
	{
		for(int i = 0; i < depth; i++)
			cout << " ";
	}
}TAB;	//全局变量,在主函数之前定义   作用:控制输出空格,缩近,无实际意义


void mmtrace::error(char *msg1, char *msg2)
{
	//ceer
	cout << "matrix error:" << msg1 << " " << msg2 << endl;
	exit(1);
}

const char *mmtrace::oname()
{
	if(!hidden)
		return name;
	const bufsz = 40;
	static char buf[bufsz];
	ostrstream obuf(buf, bufsz);
	obuf << "temporary:this = " << this << endl;
	return buf;
}

void mmtrace::object_data(char *msg)
{
	TAB.indent();
	cout << msg << ":[" << oname() << "],p = " << (int)p << endl;
}

mmtrace::mmtrace(char *object_name, int rows, int columns, double intival)
					:hidden(0), name(strdup(object_name))
//strdup函数的作用是malloc动态开辟,作参数字符串拷贝

{
	p = new matrep;
	p->m = new double* [rows];
	for(int x = 0; x < rows; x++)
	{
		p->m[x] = new double [columns];
	}
	p->n = 1;
	p->r = rows;
	p->c = columns;
	for(int i = 0; i < rows; i++)
	{
		for(int j = 0; j < columns; j++)
			p->m[i][j] = intival;
	}
	object_data("constructor called");
	TAB++;
}

mmtrace::mmtrace(mmtrace& x):hidden(1)
{
	name = strdup("temporary");
	object_data("before copy-init");
	x.object_data("copying from");
	x.p->n++;
	p = x.p;
	object_data("after copy-init");
}

mmtrace mmtrace::operator =(mmtrace& rval)
{
	object_data("op= before assignment");
	rval.object_data("op= assignment");
	rval.p->n++;
	TAB.indent();
	cout << "before decrement, referance count = " << p->n << endl;
	if(--p->n == 0)
	{
		TAB.indent();
		cout << "op = releasing old contents of [" << oname() << "]" << endl;
		for(int x = 0; x < p->r; x++)
			delete p->m[x];
		delete p->m;
		delete p;
	}
	else 
		{
			TAB.indent();
			cout << "[" << oname() << "] contents not released" << endl;
		}
	p = rval.p;
	object_data("op= returning *this");
	return *this;	//调用拷贝构造函数
	
}

mmtrace::~mmtrace()
{
	object_data("destructor called");
	TAB.indent();
	cout << "before decr, referance count = " << p->n << endl;
	if(--p->n == 0)
	{
		TAB.indent();
		cout << "destructor releasing contents of [" << oname() << "]" << endl;
		for(int x = 0; x < p->r; x++)
			delete p->m[x];
		delete p->m;
		delete p;
	}
	else 
		{
			TAB.indent();
			cout << "contents of [" << oname() << "] not released" << endl;
		}
	free(name);		//malloc开辟,在此释放
	TAB--;    
}

mmtrace mmtrace::operator +(mmtrace& rval)
{
	if((p->r != rval.p->r) || (p->c != rval.p->c))
		error("must have equal dimensions for addition!");
	object_data("in op+ called for");	//->TAB.indent();->this->oname();
	rval.object_data("op +argument");
	mmtrace sum("op+ local: sum", p->r, p->c);
	for(int i = 0; i < p->r; i++)
	{
		for(int j = 0; j < p->c; j++)
			sum.p->m[i][j] = p->m[i][j] + rval.p->m[i][j];
	}
	TAB.indent();
	cout << "in op+; returning sum" << endl;
	return sum;
}



#define TRACE(arg) TAB.indent(); cout << #arg << endl; arg

int main()
{
	/************************************************
	*	主函数开始前,TAB depth=0					*
	*	TRACE:	1.执行  TAB.indent();打印空格		*
	*			2.cout << TRACE 参数的字符串格式	*
	*			3.创建TRACE 参数,调用构造函数		*
	*************************************************/

	TRACE(mmtrace A("A", 4, 4, 3));	//每次调用构造函数,多两个空格
	TRACE(mmtrace B("B", 4, 4));
	TRACE(mmtrace C("C", 4, 4, 5));
	TRACE(mmtrace D("D", 4, 4, 6));
	TRACE(mmtrace E("E"));

	/************************************************************************************
		TRACE(E = A + B + C + D);
		步骤分解:	1.TAB.indent();再多打印打印2个空格
					2.+运算
						a.由A调用
						b.B参与运算
						c.构造sum对象
						d.return时,临时对象t1=A+B调用拷贝构造函数,使之成为sum备份
						  析构sum,但内存保留,t1指向这段内存
					3.+运算
						a.由t1调用
						b.C参与运算
						c.构造sum对象
						d.return时,临时对象t2=A+B+C调用拷贝构造函数,使之成为sum备份
						  析构sum,但内存保留,t2指向这段内存
					4.+运算
						a.由t2用
						b.D与运算
						c.构造sum对象
						d.return时,临时对象t3=A+B+C+D调用拷贝构造函数,使之成为sum备份
						  析构sum,但内存保留,t3指向这段内存
					5.=运算
						a.由E调用
						b.t3参与运算
						c.delete E 原来的空间,转指向t3
						d.return时,临时对象tE调用拷贝构造函数,使之成为E备份
					6.析构tE,实际空间保留
					7.析构t3,实际空间保留
					8.析构t2,实际空间清空
					9.析构t1,实际空间清空
					
    *************************************************************************************/
	TRACE(E = A + B + C + D);
	TAB.indent();
	cout << "After E = A + B + C + D" << endl;
	E.object_data("E");
	TAB.indent();
	cout << "Programme finishen, time for clean up" << endl;
	memory();
    return 0;

	/**************************************************
		  析构E,D,C,B,A(顺序析构),实际空间清空

		  PS.析构E(至此才实际析构)  实现由n控制
		     tE,t3,E指向同一实际的内存空间
			    构造E时,n=1;   = 运算n+1;  t3调用拷贝构造函数n+1; 
				tE析构n-1,t3析构n-1,E析构n-1,此时n=1,实际析构,释放空间
	**************************************************/

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -