1.面向对象:使用代码在计算机中模拟现实世界当中的事物
抽象:将现实世界中的属性抽象成一种特征
抽象---->属性+行为
class—>变量+方法
封装:将抽象的东西放进一个类中
类:可以看作是struct结构体的升级版
面向对象的三大特征:封装、继承、多态
面向对象的四大特征:抽象、封装、继承、多态
#ifndef MARR_H
#define MARR_H
#include<iostream>
using namespace std;
class Marr
{
public:
int* _arr;
int _len; ///总长度
int _val_len;数据个数
bool full()
{
return _len == _val_len;
}
void reserve()
{
_len = _len << 1;
int * p = new int[_len];
for (int i = 0; i < _val_len; i++)
{
p[i] = _arr[i];
}
delete[]_arr;
_arr = p;
}
Marr(int len = 10)
{
_arr = new int[len];
_len = len;
_val_len = 0;
}
~Marr()
{
delete[]_arr;
_len = 0;
_val_len = 0;
}
void push_back(int val)
{
if (full())
{
reserve();
}
_arr[_val_len++] = val;
}
int pop_back()
{
if (empty())
{
return -1;
}
return _arr[--_val_len];
}
void push_front( int val)
{
if (full())
{
reserve();
}
for (int i = _val_len; i > 0; i--)
{
_arr[i] = _arr[i - 1];
}
_arr[0] = val;
_val_len++;
}
int pop_front()
{
if (empty())
{
return -1;
}
for (int i = 0; i < _val_len - 1; i++)
{
_arr[i] = _arr[i + 1];
}
_val_len--;
return _arr[0];
}
void insert(int pos, int val)
{
if (pos < 0 || pos > _val_len)
{
return;
}
if (full())
{
reserve();
}
for (int i = _val_len; i > pos; i--)
{
_arr[i] = _arr[i - 1];
}
_arr[pos] = val;
_val_len++;
}
void erase(int pos)
{
if (empty() || pos < 0 || pos > _val_len)
{
return;
}
for (int i = pos; i < _val_len - 1; i++)
{
_arr[i] = _arr[i + 1];
}
_val_len--;
}
void show()
{
for (int i = 0; i < _val_len; i++)
{
cout << _arr[i] << " ";
}
cout << endl;
}
int find(int val)
{
for (int i = 0; i < _val_len; i++)
{
if (_arr[i] == val)
{
return i;
}
}
return -1;
}
bool empty()
{
return _val_len == 0;
}
};
#endif
2.this指针:this指针是在编译期自动加入的【指向当前对象的指针】
加在:
1.普通成员方法形参列表的第一个加上 Type* const this
2.普通成员方法体内,所有使用到普通成员的前面,加上this->
3.普通成员方法调用地方,实参列表第一个
3.构造函数:对象构造的时候会自动调用的函数【自动调用】
如果没有实现构造函数,编译器会自动生成一个默认构造函数——啥都不做
参数列表为空的构造函数为默认构造函数
一旦自己实现构造函数,编译器就不会自动生成了
构造函数可以重载
4.析构函数:对象死亡的时候调用的函数【自动调用】
如果没有实现,编译器会自动给生成一个啥都不做的空析构函数
一旦实现,编译器就不会自动生成了
析构函数没有参数,不能重载
可以手动调用,但是会出现问题,一般不建议手动调用
5.拷贝构造函数:在使用同类型的、已存在的对象去构造对象【自动调用】
如果没有实现,编译器会自动生成一个浅拷贝构造函数
一旦自己实现拷贝构造函数,编译器就不会自动生成了
6.等号运算符重载:使用已存在的对象给已存在的对象赋值【自动调用】
在使用已存在的对象给已存在的对象赋值的时候自动调用的成员方法
如果没有实现,编译器会自动给生成一个浅拷贝的等号运算符重载
一旦实现,编译器就不会自动生成了
7.权限
public:公有的,任何地方都已可以访问
private:私有的,只能类内访问
8.外界必须直接访问的。就放在public其他的放在私有,特殊情况提供公有方法
9.struct和class的区别
struct的成员默认为公有
class的成员默认为私有
10.初始化列表【只有构造函数需要初始化列表】【初始化成员变量】
类中所有普通成员变量都会在初始化列表进行初始化
类中必须手动初始化的普通成员,必须手动放在初始化列表
11.静态成员 static
静态成员访问可以使用作用域,不依赖于this指针,必须初始化,放在类外初始化
静态成员方法没有this参数
静态成员方法内只能使用静态成员
12.const方法
常量对象只能调用常方法
如果方法不改变对象的值,就加上
修饰this指针,常指针
13.设计模式
单例模式:【只能产生一个对象,都能获取对象】
把构造放入私有,提供一个静态的成员方法
mlist.h
#ifndef MLIST_H
#define MLIST_H
#include<iostream>
using namespace std;
class Node
{
public:
Node(int val = int())
:_val(val),_next(nullptr),_pre(nullptr)
{
}
Node(const Node& src)
:_val(src._val), _next(nullptr), _pre(nullptr)
{}
Node& operator=(const Node& src)//传引用是为了防止死递归
{
_val = src._val;
_next = NULL;
_pre = NULL;
}
int get_val();
void set_val(int val);
Node* get_next();
void set_next(Node* next);
Node* get_pre();
void set_pre(Node* pre);
private:
int _val;
Node* _next;
Node* _pre;
};
class List
{
public:
typedef Node LIST_NODE_TYPE;
List();
~List();
void push_back(int val);
int pop_back();
void push_front(int val);
int pop_front();
int back();
int front();
bool empty();
void show()
{
LIST_NODE_TYPE * tmp = _head->get_next();
while (tmp != NULL)
{
cout << tmp->get_val() << " ";
tmp = tmp->get_next();
}
cout << endl;
}
private:
LIST_NODE_TYPE* _head;
LIST_NODE_TYPE* _tail;
};
#endif
mlist.cpp
#include"mlist.h"
int Node::get_val()
{
return _val;
}
void Node::set_val(int val)
{
_val = val;
}
Node* Node::get_next()
{
return _next;
}
void Node::set_next(Node* next)
{
_next = next;
}
Node* Node::get_pre()
{
return _pre;
}
void Node::set_pre(Node* pre)
{
_pre = pre;
}
List::List()
{
_head = new LIST_NODE_TYPE();
_tail = _head;
}
List::~List()
{
while (!empty())
{
pop_front();
}
delete _head;
_head = _tail = NULL;
}
void List::push_back(int val)
{
LIST_NODE_TYPE * node = new LIST_NODE_TYPE(val);
node->set_pre(_tail);
_tail->set_next(node);
_tail = node;
}
int List::pop_back()
{
if (empty())
{
return -1;
}
int val = _tail->get_val();
_tail = _tail->get_pre();
delete _tail->get_next();
_tail->set_next(NULL);
return val;
}
void List::push_front(int val)
{
LIST_NODE_TYPE* node = new LIST_NODE_TYPE(val);
node->set_pre(_head);
node->set_next(_head->get_next());
_head->set_next(node);
if (!empty())
{
node->get_next()->set_pre(node);
}
else
{
_tail = node;
}
}
int List::pop_front()
{
if (empty())
{
return -1;
}
LIST_NODE_TYPE* node = _head->get_next();
int val = node->get_val();
_head->set_next(node->get_next());
if (node != _tail)
{
node->get_next()->set_pre(_head);
}
else
{
_tail = _head;
}
delete node;
return val;
}
int List::back()
{
if (empty())
{
return -1;
}
return _tail->get_val();
}
int List::front()
{
if (empty())
{
return -1;
}
return _head->get_next()->get_val();
}
bool List::empty()
{
return _tail == _head;
}
mstack.h
#ifndef MSTACK_H
#define MSTACK_H
#include"mlist.h"
#include<mutex>
class Stack
{
public:
void pop()
{
_list.pop_back();
}
void push(int val)
{
_list.push_back(val);
}
int top()
{
return _list.back();
}
bool empty()
{
return _list.empty();
}
static Stack* get_only_stack()
{
if (NULL == _stack_only)
{
_lock->lock();
if (NULL == _stack_only)
{
_stack_only = new Stack();
}
_lock->unlock();
}
return _stack_only;
}
//将自动生成的成员方法删除
Stack(const Stack& src) = delete;
private:
Stack() {}
static Stack* _stack_only;
static mutex* _lock;
List _list;
};
#endif
main.cpp
#include<iostream>
#include"mlist.h"
#include"mstack.h"
using namespace std;
Stack* Stack::_stack_only = NULL;
mutex* Stack::_lock = new mutex();
void fun()
{
List list1;
for (int i = 0; i < 5; i++)
{
list1.push_back(i);
}
list1.show();
for (int i = 5; i < 10; i++)
{
list1.push_front(i);
}
list1.show();
for (int i = 0; i < 10; i++)
{
list1.pop_front();
list1.show();
}
for (int i = 5; i < 10; i++)
{
list1.push_front(i);
}
list1.show();
Stack* p = Stack::get_only_stack();
//Stack sta(*p);
//Stack* p1 = new Stack(*p);
}
int main()
{
fun();
system("pause");
return 0;
}