www.gusucode.com > 《C++高级语言程序设计》PPT及全书例子源代码-源码程序 > 《C++高级语言程序设计》PPT及全书例子源代码-源码程序/code/C++例题程序/第4章/s4_12/sclass4_12_Node.cpp
//Download by http://www.NewXing.com //类的实现文件 //文件名:ch4_12\sclass4_12_Node.cpp #include "sclass4_12_Node.h" //包含类定义头文件 //Node无参构造函数 //Node::Node() //{ // m_lpszChar = NULL; // m_iValue = 0; // cout << "调用了无参构造函数Node: " << endl; //} //Node带参构造函数 Node::Node(char *lpszChar, int iValue) //结点构造函数 { assert(lpszChar); //断言lpszChar非空 m_lpszChar = new char[strlen(lpszChar)+1]; //new结点命名空间 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(0); //内存分配失败,退出 } strcpy(m_lpszChar, lpszChar); m_iValue = iValue; //结点值初始为0 cout << "调用了带参构造函数Node: " << m_lpszChar << endl; } //Node的拷贝构造函数 Node::Node(const Node &oNode) { m_lpszChar = new char[strlen(oNode.m_lpszChar)+1]; //new结点命名空间 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(0); } strcpy(m_lpszChar, oNode.m_lpszChar); m_iValue = oNode.m_iValue; //结点值初始为0 cout << "调用了拷贝构造函数Node:" << m_lpszChar << endl; } //Node的析构函数 Node::~Node() { cout << "调用了析构函数Node: " << m_lpszChar << endl; delete m_lpszChar; //当m_lpszChar==NULL时,也可以delete,不会出错 } //Node的赋值运算符重载 Node &Node::operator=(const Node &oNode) { if (this == &oNode) //判断是否自己赋值给自己 { return *this; } delete m_lpszChar; //释放原字符数组空间 m_lpszChar = new char[strlen(oNode.m_lpszChar)+1]; //new字符数组空间 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(0); } strcpy(m_lpszChar, oNode.m_lpszChar); m_iValue = oNode.m_iValue; //结点值初始为0 cout << "调用了重载'='运算符Node:" << m_lpszChar << endl; return *this; } //CNodeArray类的构造函数 CNodeArray::CNodeArray(int iTotalNodeNum) //结点数组构造函数 { for (int i=0; i<iTotalNodeNum; i++) { m_pNode[i] = NULL; //指针数组初始化,数组内的指针全部指向NULL } m_aLength = iTotalNodeNum; //数组长度设置 m_aCurrentTop = 0; //当前结点设置为0 cout << "调用了构造函数CNodeArray:" << endl; } //CNodeArray的拷贝构造函数。const引用作参数,可保证实参的安全性 //如果大家的长度不等就不应该复制。 CNodeArray::CNodeArray(const CNodeArray &oCNodeArray) { //在[0~m_aCurrentTop-1]之间,有Node结点,所以需要新建结点 for (int i=0; i<oCNodeArray.m_aCurrentTop; i++) { //创建一个新结点,并将oCNodeArray上对应结点的内容复制过来 m_pNode[i] = new Node(oCNodeArray.m_pNode[i]->m_lpszChar, oCNodeArray.m_pNode[i]->m_iValue); if (m_pNode[i] == NULL) //判断内存分配是否成功 { cout << "内存分配失败!" << endl; exit(0); } } //在[m_aCurrentTop~m_aLength-1]之间,没有Node结点,全为NULL for (i=oCNodeArray.m_aCurrentTop; i<oCNodeArray.m_aLength; i++) { m_pNode[i] = NULL; } m_aLength = oCNodeArray.m_aLength; //复制数组长度的值 m_aCurrentTop = oCNodeArray.m_aCurrentTop; //复制当前结点标号值 cout << "调用了拷贝构造函数CNodeArray:" << endl; } //析构函数 CNodeArray::~CNodeArray(void) //析构函数 { for (int i=0; i<m_aCurrentTop; i++) { delete m_pNode[i]; //自动调用~Node( ) } cout << "调用了析构函数CNodeArray。" << endl; } //插入一个结点。插入位置在m_aCurrentTop处。这里通过指针数组中的指针操作其所指向的结点 //其插入和删除有点类似堆栈的性质:只在top端,插入,删除 bool CNodeArray::Insert(const Node &oNode) //插入一个结点 { if( m_aCurrentTop>=m_aLength ) { cout << "对不起,已经超过了数组最大长度,不可再插入!" << endl; return false; } //将要插入的结点复制到结点数组中 m_pNode[m_aCurrentTop] = new Node(oNode.m_lpszChar, oNode.m_iValue); if (m_pNode[m_aCurrentTop] == NULL) { cout << "创建结点失败!" << endl; exit(0); } m_aCurrentTop++; //当前结点值m_aCurrentTop+1,下一次插入的位置 cout << "插入了一个结点: " << oNode.m_lpszChar << endl; return true; } //删除一个结点。每次删除都删除m_aCurrentTop-1的对应结点。相当于结点出栈 bool CNodeArray::Del(void) //删除一个结点 { if (!IsEmpty()) //如果指针数组非空,则执行删除操作 { m_aCurrentTop--; //首先将当前结点值减1。当前结点实际上还没有内容 cout << "删除的结点名字为:" << m_pNode[m_aCurrentTop]->m_lpszChar << endl; delete m_pNode[m_aCurrentTop]; //释放当前结点 return true; } else { cout << "结点数组为空。不能够执行删除操作。Is Empty\n"; return false; } } //判断结点指针数组中是否有结点 bool CNodeArray::IsEmpty(void) { if (m_aCurrentTop == 0) { return true; //为空返回true } else { return false; //不为空返回false } } //CNodeArray的','运算符重载 const CNodeArray & CNodeArray::operator,(const CNodeArray &oCNodeArray) { return oCNodeArray; //直接返回第二操作数 } //CNodeArray的'[ ]'运算符重载 char *CNodeArray::operator[](int i) { if ((i < m_aCurrentTop)&&(m_aCurrentTop >=0)) { return m_pNode[i]->m_lpszChar; //返回第i个结点的字符串 } else { return ("数组越界。"); } } //赋值运算符重载。其重载函数体与拷贝构造函数相同可调用完成。但重载赋值运算符需要 //首先释放调用对象的相关动态内存 CNodeArray & CNodeArray::operator=(const CNodeArray &oCNodeArray) { if (this == &oCNodeArray) //首先判断是否自己赋值给自己 { return *this; } //这里需要考虑两个对象的m_aLength属性是否相同,否则会产生数组越界的问题 //这里的指针数组是非动态的,不可调整大小 if (m_aLength != oCNodeArray.m_aLength) { cout << "数组长度不等,不能够复制!" << endl; return *this; } //首先进行释放工作,释放this对象所使用到的所有动态内存空间 for (int i=0; i<m_aCurrentTop; i++) { delete m_pNode[i]; //释放指针数组中的每个指针所指向的动态内存空间,=NULL m_pNode[i] = NULL; } //此后可进行对象复制工作。此处是一个深度复制过程,在复制中需要新建(new)Node //类型的对象数组空间,所以用了Node的构造函数 //在[0~m_aCurrentTop-1]之间,有Node结点,所以需要新建结点 for (i=0; i<oCNodeArray.m_aCurrentTop; i++) { //创建一个新结点,并将oCNodeArray上对应结点的内容复制过来 m_pNode[i] = new Node(oCNodeArray.m_pNode[i]->m_lpszChar, oCNodeArray.m_pNode[i]->m_iValue); if (m_pNode[i] == NULL) //判断内存分配是否成功 { cout << "内存分配失败!" << endl; exit(0); } } //在[m_aCurrentTop~m_aLength-1]之间,全为NULL for (i=oCNodeArray.m_aCurrentTop; i<oCNodeArray.m_aLength; i++) { m_pNode[i] = NULL; } m_aLength = oCNodeArray.m_aLength; //复制数组长度的值 m_aCurrentTop = oCNodeArray.m_aCurrentTop; //复制当前结点标号值 cout << "调用重载运算符'='CNodeArray:" << endl; return *this; } //重载new void *CNodeArray::operator new(size_t size) { cout << "自定义的 CNodeArray new\n"; return malloc(size); } //重载delete void CNodeArray::operator delete(void *p) { cout << "自定义的 CNodeArray delete\n"; free(p); } //重载输出运算符, ostream &operator << (ostream & scout, CNodeArray obj) { scout << obj.m_pNode[obj.m_aCurrentTop-1]->m_lpszChar << ","; scout << obj.m_pNode[obj.m_aCurrentTop-1]->m_iValue << ","; scout << obj.m_aLength << ","; scout << obj.m_aCurrentTop << endl; return scout; } //重载输入运算符 istream &operator >> (istream &scin, CNodeArray &obj) { int iTemp = 0; char *lpszChar = new char[100]; cout << "请输入操作下标:"; scin >> iTemp; if( iTemp>=obj.m_aCurrentTop ) { cout << "你输入的节点下标大于当前节点值:" << obj.m_aCurrentTop << endl; // cout << "对不起,你的操作是错误的!" << endl; exit(0); } cout << "请输入结点值:"; scin >> obj.m_pNode[iTemp]->m_iValue; cout << "结点原名字为:" << obj.m_pNode[iTemp]->m_lpszChar << endl; cout << "请输入结点新名字:" << endl; scin.get(); scin.getline(lpszChar,20); //从输入流中取得一行,新结点名字 delete obj.m_pNode[iTemp]->m_lpszChar; //释放原来的内存空间 obj.m_pNode[iTemp]->m_lpszChar = lpszChar; //指向新的内存空间 cout << "现名字为:" << obj.m_pNode[iTemp]->m_lpszChar << endl; return scin; }