(1)node.h
#ifndef NODE_H
#define NODE_H
#include<iostream>
using namespace std;
class List;
void show(List& list);
class Node
{
public:
Node(int val = int())
{
_val = val;
_next = NULL;
_pre = NULL;
}
friend class List;//友元类
friend void show(List& list);//友元函数
private:
int _val;
Node* _next;
Node* _pre;
};
#endif
(2)stack.h
#ifndef STACK_H
#define STACK_H
#include"list.h"
class Stack
{
public:
Stack()
:_list(10)
{
cout << "Stack()" << endl;
}
~Stack()
{
cout << "~Stack()" << endl;
}
void push(int val)
{
_list.push_back(val);
}
void pop()
{
_list.pop_back();
}
int top()
{
return _list.back();
}
bool is_empty()
{
return _list.is_empty();
}
private:
List _list;
};
#endif
(3)main.cpp
#include<iostream>
#include"list.h"
#include"stack.h"
using namespace std;
/*
类与类之间的关系
组合:::: ---------》一个类是另一个类的一部分 eye head
嵌套
一个类在另一个类的内部实现
权限属性依然生效
外界访问嵌套类需要用到外层类的作用域
成员对象
构造顺序::先构造成员对象,再构造自身对象
析构::::先析构自身对象,再析构成员对象
如果成员对象没有默认的构造函数,就必须手动写在初始化列表
代理
一个类的接口功能完全依赖于另一个类的接口功能
*/
/*
成员变量必须放在成员方法的前面,
否则成员方法编译时候无法知道成员变量的存在 error
类的编译顺序:
编译类名
编译成员名======编译嵌套类(类名,成员名)
编译成员方法体
*/
void show(List& list);
int main()
{
/*
List list1;
for (int i = 0; i < 5; i++)//0,1,2,3,4
{
list1.push_back(i);
}
for (int i = 0; i < 5; i++)//4,3,2,1,0,0,1,2,3,4
{
list1.push_front(i);
}
show(list1);
List list2 = list1;
show(list2);
cout << "==========================" << endl;
list1.pop_back();
show(list1);
show(list2);
//List::Node* node;
*/
Stack _sta;
return 0;
}
(4)list.h
#ifndef LIST_H
#define LIST_H
//#include"node.h"
#include<iostream>
using namespace std;
class List;
void show(List& list);
class List
{
public:
List(int a);
List(const List& src);
~List();
List& operator=(const List& src);
void push_back(int val);
void pop_back();
void push_front(int val);
void pop_front();
int back();
int front();
bool is_empty();
Node* show11()
{
Node* p;
p->_next;
p->fun();
}
friend void show(List& list);
private:
class Node
{
public:
Node(int val = int())
{
_val = val;
_next = NULL;
_pre = NULL;
}
void fun() {
};
friend class List;//友元类
friend void show(List& list);//友元函数
private:
int _val;
Node* _next;
Node* _pre;
};
Node* _head;
Node* _tail;
};
#endif
(5)list.cpp
#include"list.h"
/*
类内实现的成员方法默认会被建议为内联----inline
更多时候对于大一点的类会选择类外实现----查看代码更清晰
*/
List::List(int a)
{
cout << "List() " << endl;
_head = new Node();
_tail = _head;
}
List::List(const List& src)
{
//申请新节点
_head = new Node();
_tail = _head;
//从前向后遍历src链表,将每个数据push_back插入到新链表
Node* tmp = src._head->_next;
while (NULL != tmp)
{
push_back(tmp->_val);
tmp = tmp->_next;
}
}
List::~List()
{
cout << "~List()" << endl;
//当前链表不为空的时候,就一直删除
while (!is_empty())
{
pop_back();
}
//删除头结点
delete _head;
}
List& List::operator=(const List& src)
{
if (this == &src)
{
return *this;
}
//删除所有的当前有效节点
while (!is_empty())
{
pop_back();
}
//从前向后遍历src,将src中的数据push_back到当前链表
Node* tmp = src._head->_next;
while (NULL != tmp)
{
push_back(tmp->_val);
tmp = tmp->_next;
}
return *this;
}
void List::push_back(int val)
{
//申请节点
Node* node = new Node(val);
_tail->_next = node;
node->_pre = _tail;
_tail = node;
}
void List::pop_back()
{
if (is_empty())
{
return;
}
_tail = _tail->_pre;
delete _tail->_next;
_tail->_next = NULL;
}
void List::push_front(int val)
{
Node* tmp = new Node(val);
//当前如果链表不为空,就需要处理第一个实际节点
if(!is_empty())
{
tmp->_next = _head->_next;
_head->_next->_pre = tmp;
}
else
{
//如果链表为空,就需要将tail指向当前新增的节点
_tail = tmp;
}
//将新增节点连接到_head上
_head->_next = tmp;
tmp->_pre = _head;
}
void List::pop_front()
{
if (is_empty())
{
return;
}
Node* tmp = _head->_next;
//如果当前节点不是最后一个节点
if (NULL != tmp->_next)
{
tmp->_next->_pre = _head;
}
else
{
//如果删除的是当前链表的唯一实际节点
_tail = _head;
}
_head->_next = tmp->_next;
delete tmp;
}
int List::back()
{
if (is_empty())
{
return -1;
}
return _tail->_val;
}
int List::front()
{
if (is_empty())
{
return -1;
}
return _head->_val;
}
bool List::is_empty()
{
return _head == _tail;
}
void show(List& list)
{
List::Node* tmp = list._head->_next;
while (tmp != NULL)
{
cout << tmp->_val << "->";
tmp = tmp->_next;
}
cout << endl;
}
10_14
1.友元(friend)
友元函数
2.类与类之间的关系
组合类:一个类是另一个类的一部分
①嵌套类:一个类在另一个类的内部实现,同样具有权限属性,外界访问嵌套类需要用到外层类的作用域。
②子成员:
③代理类:一个类的接口功能完全依赖于另一个类的接口实现。
先构造成员对象,在构造自身对象,析构时先析构自身对象,再析构成员对象
如果成员对象没有默认的构造函数,就必须自己实现
3.类的编译顺序
(1)编译类名
(2)编译成员名(嵌套类编译)
(3)编译成员方法体