#include <iostream>
#include <memory>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
class Counted
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
class TooManyObjects
{};
static size_t getObjectsNum();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
protected:
Counted();
Counted(Counted&);
~Counted();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
private:
void init();
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
private:
static size_t numObjects;
static const size_t maxObjects;
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
size_t Counted<BeingCounted>::numObjects = 0;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
size_t Counted<BeingCounted>::getObjectsNum()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
return numObjects;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
Counted<BeingCounted>::Counted()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
init();
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
Counted<BeingCounted>::Counted(Counted&)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
init();
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
Counted<BeingCounted>::~Counted()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
--numObjects;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<typename BeingCounted>
void Counted<BeingCounted>::init()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
if( numObjects >= maxObjects )throw TooManyObjects();
++numObjects;
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**////////////////////////////////////////////////![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
class Printer:private Counted<Printer>
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public:
using Counted<Printer>::getObjectsNum;
using Counted<Printer>::TooManyObjects;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
public:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
static Printer* make_aPrinter()
{return new Printer;}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
static Printer* make_aCopy(const Printer& rhs)
{return new Printer(rhs);}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
private:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Printer()
{}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Printer(const Printer& rhs)
{}
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
template<>
const size_t Counted<Printer>::maxObjects = 4;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
try
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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() );
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "current object number: "<< Printer::getObjectsNum() << endl;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
auto_ptr<Printer> p4( Printer::make_aCopy( *p1 ) );
}
catch( Counted<Printer>::TooManyObjects& exp )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cout << "exception happened" << endl;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
cout << "current object number: "<< Printer::getObjectsNum() << endl;
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)