#include <iostream>
#include <memory>
using namespace std;
template<typename BeingCounted>
class Counted
{
public:
class TooManyObjects{};
static size_t getObjectsNum();
protected:
Counted();
Counted(Counted&);
~Counted();
private:
void init();
private:
static size_t numObjects;
static const size_t maxObjects;
};
template<typename BeingCounted>
size_t Counted<BeingCounted>::numObjects = 0;
template<typename BeingCounted>
size_t Counted<BeingCounted>::getObjectsNum()
{
return numObjects;
}
template<typename BeingCounted>
Counted<BeingCounted>::Counted()
{
init();
}
template<typename BeingCounted>
Counted<BeingCounted>::Counted(Counted&)
{
init();
}
template<typename BeingCounted>
Counted<BeingCounted>::~Counted()
{
--numObjects;
}
template<typename BeingCounted>
void Counted<BeingCounted>::init()
{
if( numObjects >= maxObjects )throw TooManyObjects();
++numObjects;
}
/**////////////////////////////////////////////////
class Printer:private Counted<Printer>
{
public:
using Counted<Printer>::getObjectsNum;
using Counted<Printer>::TooManyObjects;
public:
static Printer* make_aPrinter(){return new Printer;}
static Printer* make_aCopy(const Printer& rhs){return new Printer(rhs);}
private:
Printer(){}
Printer(const Printer& rhs){}
};
template<>
const size_t Counted<Printer>::maxObjects = 4;
int main()
{
try
{
auto_ptr<Printer> p1( Printer::make_aPrinter() );
auto_ptr<Printer> p2( Printer::make_aPrinter() );
auto_ptr<Printer> p3( Printer::make_aPrinter() );
auto_ptr<Printer> p5( Printer::make_aPrinter() );
cout << "current object number: "<< Printer::getObjectsNum() << endl;
auto_ptr<Printer> p4( Printer::make_aCopy( *p1 ) );
}
catch( Counted<Printer>::TooManyObjects& exp )
{
cout << "exception happened" << endl;
}
cout << "current object number: "<< Printer::getObjectsNum() << endl;
return 0;
}