📄 mmtrace.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 + -