同时定义前缀式操作符和后缀式操作符存在一个问题:它们的形参数目和类型相同,普通重载不能区别所定义的是前缀式操作还是后缀式操作。通常后缀式操作符重载函数接受一个额外的int型形参,编译器提供0作为这个形参的实参。
前缀式操作返回改变后的值,所以返回对象的引用,而后缀式操作符应返回旧值,所以作为值返回。
#include<iostream>
#include<string>
using namespace std;
class CheckedPtr
{
public:
CheckedPtr(int *b,int *e):beg(b),end(e),cur(b){}
CheckedPtr& operator++();//前置++
CheckedPtr& operator--();
CheckedPtr operator++(int);//后置++
CheckedPtr operator--(int);
private:
int* beg;//指向数组的第一个元素
int* end;//指向数组的末端
int* cur;//指向CheckedPtr对象当前引用的数组元素
};
CheckedPtr& CheckedPtr::operator++()
{
if(cur == end)
cout << "out_of_range" << endl;
++cur;
return *this;
}
CheckedPtr& CheckedPtr::operator--()
{
if(cur == beg)
cout << "out_of_range" << endl;
--cur;
return *this;
}
CheckedPtr CheckedPtr::operator++(int)
{
CheckedPtr ret(*this);//记住对象在++前的状态
++*this;
return ret;
}
CheckedPtr CheckedPtr::operator--(int)
{
CheckedPtr ret(*this);
--*this;
return ret;
}
类型重载
#include<iostream>
#include<string>
using namespace std;
class CInt
{
public:
CInt(int a):ma(a){}
/*
bool operator<(int rhs)
{
return ma<rhs;
}
*/
CInt& operator++()
{
++ma;
return *this;
}
/*
int operator[](int* arr)
{
return arr[ma];
}
*/
operator int()//类型重载
{
return ma;
}
private:
int ma;
};
int main()
{
int arr[] = {10,4,6,7,9,3};
int len = sizeof(arr)/sizeof(arr[0]);
for(CInt i=0; i<len; ++i)
{
cout << i[arr] << endl;
}
return 0;
}
new和delete重载
a.cpp CMEMPool pool1;
b.cpp CMEMPool pool2;
pool1和pool2两个不同的对象,分别管理各自的已使用的部分,未使用的部分由pool统一管理,也就是同一类型的对象使用一个内存池,所以设计成单例模式。
#include<iostream>
using namespace std;
const int MEM_POOL_SIZE = 10;
template<typename T>
class CMemPool
{
public:
void* alloc(size_t size);
void del(void* ptr);
static CMemPool& getIntance()
{
return single;
}
private:
CMemPool(){}
CMemPool(const CMemPool<T>& rhs){}
class Node
{
public:
char p[sizeof(T)]; //对象要使用
Node* pnext; //管理内存池静态链表的指针
};
static Node* pool;//指向空闲链
static CMemPool<T> single;
};
template<typename T>
CMemPool<T> CMemPool<T>::single;
template<typename T>
typename CMemPool<T>::Node* CMemPool<T>::pool = NULL;
template<typename T>
void* CMemPool<T>::alloc(size_t size)
{
if (pool == NULL)
{
int allocsize = (size + 4)*MEM_POOL_SIZE;
pool = (Node*)new char[allocsize];
Node* pCur = pool;
for (pCur; pCur < pool + MEM_POOL_SIZE - 1; ++pCur)
{
pCur->pnext = pCur + 1;
}
pCur->pnext = NULL;
}
Node* rt = pool;
pool = pool->pnext;
return rt;
}
template<typename T>
void CMemPool<T>::del(void* ptr)
{
if (ptr == NULL)
return;
Node* deleteptr = (Node*)ptr;
deleteptr->pnext = pool;
pool = deleteptr;
}
class CStu
{
public:
CStu(int id = 0, int age = 18, float score = 0.0f)
:mid(id), mage(age), mscore(score){}
void* operator new(size_t size)
{
return mpool->alloc(size);
}
void operator delete(void* ptr)
{
mpool->del(ptr);
}
private:
int mid;
int mage;
float mscore;
static CMemPool<CStu> *mpool;
};
CMemPool<CStu>* CStu::mpool = &CMemPool<CStu>::getIntance();
int main()
{
CStu* st1 = new CStu(10);
CStu* st2 = new CStu(10);
CStu* st3 = new CStu(10);
CStu* st4 = new CStu(10);
CStu* st5 = new CStu(10);
CStu* st6 = new CStu(10);
return 0;
}