首页 > 其他分享 ><八>通过new和delete重载实现对象池的应用

<八>通过new和delete重载实现对象池的应用

时间:2022-11-25 17:33:33浏览次数:43  
标签:front nullptr next QueueItem 重载 new tep rear delete

MyQueue版本1

#include <iostream>
using namespace std;

template<typename T>
class MyQueue {

private:

	struct QueueItem {
		QueueItem(T _data = T(), QueueItem  * _next = nullptr)
			:data(_data),
			next(_next) {
			next = nullptr;
		}
		T  data;
		QueueItem  * next;
	};
	QueueItem * _front;//指向队头
	QueueItem * _rear; //指向队尾

public:

	//队尾入队操作
	void push(T & _value) {
		QueueItem *tep = new QueueItem(_value, nullptr);
		_rear->next = tep;
		_rear = tep;
	}
	//队头出队操作
	void pop() {
		if (empty()) { return; }
		QueueItem *tep = _front->next;
		_front->next = tep->next;
		//如果队中只有一个元素,被删除了,由于这个出队的元素要delete,所以,_rear 就丢失信息了,这个时候要记得把_rear=nullprt
		if (_front->next == nullptr) { _rear = nullptr; }
		delete tep;
	}

	//队是否为空
	bool empty() {
		return _front = _rear;
	}

	~MyQueue() {
		QueueItem *current = _front;
		while (current != nullptr) {
			_front = _front->next;
			delete current;
			current = _front;
		}
	}

	MyQueue<T>() {
		QueueItem *tep = new QueueItem;
		_front = tep;
		_rear = tep;
	}


	T front()  {
	   return  _front->next; ->data;
	}
};

int main() {

	MyQueue<int> mq;
	for (int i = 0; i < 10000000; i++) {
		mq.push(i);
		mq.pop();
	}

	bool isEmpty = mq.empty();

	cout << isEmpty << endl;

	system("pause");
	return 0;
}

上面代码有个效率问题,循环 10000000 次,一直在创建 对象,和销毁对象. 如何优化?

MyQueue版本2

#include <iostream>
using namespace std;


template<typename T>
class MyQueue {

private:

	struct QueueItem {
		
		QueueItem(T _data = T(), QueueItem  * _next = nullptr)
			:data(_data),
			next(_next) {
			next = nullptr;
		}

		//分配内存
		void * operator new(size_t size) {
			
			if (poolItemList == nullptr) {
				
				//预先申请内存空间			
				poolItemList = (QueueItem *) new char[sizeof(QueueItem) * POOL_ITEM_SIZE];
				QueueItem * tp = poolItemList;
				//把上面申请的内存空间 按照 一个 一个 QueueItem 串到队列中
				while (tp < poolItemList + POOL_ITEM_SIZE -1) {
					tp->next = tp + 1;
					++tp;
				}
				tp->next = nullptr;
				cout << "1:申请缓存池空间" << poolItemList << endl;
				
			}
			
			QueueItem *  returnPoint = poolItemList;
			poolItemList = poolItemList->next;	
		//	cout << "申请QueueItem节点空间" << returnPoint << endl;
			return returnPoint;
			
		}

		//将使用过的内存还会去
		void operator delete(void * ptr) {
			
			//归还的内存放回到链表头部
			if (ptr != nullptr) {
				QueueItem * qptr = (QueueItem *)ptr;		
				QueueItem *	tp_poolItemList = poolItemList;
				qptr->next   = poolItemList;
				poolItemList = qptr;
			//	cout << "归还空间" << ptr << endl;
			}

		}

		T  data;
		QueueItem  * next;
		static  const   int  POOL_ITEM_SIZE = 10000;
		static  QueueItem    * poolItemList ;

	};
	
	
	QueueItem * _front;//指向队头
	QueueItem * _rear; //指向队尾
	
	
public:

	//构造函数
	MyQueue<T>() {
		QueueItem *tep = new QueueItem();
		_front = tep;
		_rear  = tep;
	}

	~MyQueue() {
		QueueItem *current = _front;
		while (current != nullptr) {
			_front = _front->next;
			delete current;
			current = _front;
		}
	}


	//队尾入队操作
	void push(T & _value) {
		QueueItem *tep = new QueueItem(_value, nullptr);
		_rear->next = tep;//原来队尾元素的下一节点设置为当前申请节点
		_rear = tep;
	}

	//队头出队操作
	void pop() {
		if (empty()) { return; }
		QueueItem *first = _front->next;
		_front->next = first->next;
		//如果队中只有一个元素,被删除了,由于这个出队的元素要delete,所以,_rear 就丢失信息了,这个时候要记得把_rear=nullprt
		if (_front->next == nullptr) { _rear = _front; }
		delete first;
	}

	//队是否为空
	bool empty() {
		return _front == _rear;
	}

	T front()  {
	   return  _front->next->data;
	}


};

template<typename T>
typename MyQueue<T>::QueueItem *  MyQueue<T>::QueueItem::poolItemList =nullptr;


int main() {

	MyQueue<int> mq;
	for (int i = 0; i < 100000; i++) {
		mq.push(i);
		mq.pop();
	}

	bool isEmpty = mq.empty();

	cout << isEmpty << endl;

	system("pause");

	return 0;

}

标签:front,nullptr,next,QueueItem,重载,new,tep,rear,delete
From: https://www.cnblogs.com/erichome/p/16919768.html

相关文章

  • 【iOS-cocos2d-X 游戏开发之十一】New CCSprite()带来的错误&使用CCUserDefault及pvr.
    本站文章均为​​ 李华明Himi ​​​原创,转载务必在明显处注明本章讲解的是几个细节问题,但是此细节有可能导致一系列问题,那么今天Himi与童鞋们共同交流分享下;一.  对......
  • Numpy | np.newaxis()函数
    np.newaxisnp.newaxis的功能是增加新的维度,但是要注意np.newaxis放的位置不同,产生的矩阵形状也不同。通常按照如下规则:np.newaxis放在哪个位置,就会给哪个位置增加维......
  • Java9集合类中重载多个of方法原因
    在java9api的集合类中,有很多看似一样的重载of方法:那这里有个问题是为什么有了VarArgs(可变长参数)方法,还需要定义那么多重载的方法呢?查看官方的更新日志中可以发现有如下描......
  • 关于new integer(1)==new integer(1)
    先上测试代码:publicclassTest{publicstaticvoidmain(String[]args){Integerl1=newInteger(1);Integerl2=newInteger(1);......
  • <七>深入理解new和delete的原理
    new,delete运算符int*p=newint;deletep;看一下汇编代码可以看到new和delete运算符其实也是operator运算符重载函数的调用malloc和newmalloc按字节开辟内......
  • 用汇编的眼光看C++(之算术符重载)
       算术符重载是类的有一个特性,但是每个人使用的方法不一样。用的好,则事半功倍;但是如果不正确的使用,则会后患无穷。   (1)简单算术符介绍   那什么是算术符重载......
  • mysqlexecdelete_sql
    #!/bin/bash#auther:don2022/09/30#version01mysql_bin="mysql6603"mysql_user="root"mysql_password="xxxxxx"mysql_sock_path="/home/mysql_6603/mysql.sock"#sql_quer......
  • C++语言运算符重载
     概念    在C语言中,运算符只能用于基本数据类型,例如,可以用==判断两个整数是否相等,但不能用于判断字符串是否相等,也不能用于判断结构体,也不能用于判断类。   ......
  • C++语言函数重载详解和示例
     C++函数重载的概念在实际开发中,有时候我们需要实现几个功能类似的函数,只是有些细节不同。例如把变量的值写入文件,变量的类型int、long、double、char,需要通过参数把变量......
  • C++学习笔记--new和delete运算符
    //#include<iostream>//usingnamespacestd;////intmain()//{// ////使用new申请一个新的空间// ////int*p1=newint; //申请一个新的空间,new+type后面的类型要和前......