在C++中计算物件个数(Objects Counting in C++)

原文出自:More Effective C++ 电子版 p.452 

仅为个人学习,暴露缺点;所以仅供参考,欢迎讨论!

 

需求:当我需要实时了解当前有多少类型的对象同时存在。

设计:比如一开始会这样设计

  
    
class Widget {
public :
Widget() {
++ count; }
Widget(
const Widget & ) { ++ count; }
~ Widget() { -- count; }
static size_t howMany() { return count; }

private :
static size_t count;
};

 

直接在类中增加一个static member data。然后当Widget类型有对象被构造(复制构造)时计数器+1,析构时计数器-1;如果目标仅仅是针对Widget类的话,我们的需求已经被达到了。

但是,当我们需要统计不同类型的对象个数时,就需要换一种更为舒服的实现方式了。

设计一个计数类:

  
    
class Counter {
public :
Counter() {
++ count; }
Counter(
const Counter & ) { ++ count; }
~ Counter() { -- count; }
static size_t howMany()
{
return count; }
private :
static size_t count;
};

 

  
    
// 在需要计数的 class 中内嵌一个Counter object。
class Widget {
public :
.....
// Widget 该有的所有public 成员,
// 都放在这里。
static size_t howMany()
{
return Counter::howMany(); }
private :
.....
// Widget 该有的所有private 成员,
// 都放在这里。
Counter c;
};

// 另一个方法是把Counter 当做base class,像这样:
// 让需要计数的class 继承自Counter
class Widget: public Counter {
.....
// Widget 该有的所有public 成员,
// 都放在这里。
private :
.....
// Widget 该有的所有private 成员,
// 都放在这里。
};

 

但是这样设计的话又会出现一个问题,看出来了么?

对,就是static的count。如果我们同时存在A类和B类需要计数,那我们则需要2个static size_t count,而不是一个!

运用C++ 中最广为人知但名称十分诡异的一个技俩:

  
    
template < class T >
class Counter {
public :
Counter() {
++ count; }
Counter(
const Counter & rhs){ ++ count; }
virtual ~ Counter() { -- count; }
static size_t hMany() { return count; }
private :
static size_t count;
};

template
< class T >
size_t Counter
< T > ::count = 0 ;

 

现在,Counter 成了一个 template,不论内嵌式设计或继承式 设计,都可以运作了。

  
    
class Widget : private Counter < Widget >
{
public :
using Counter < Widget > ::hMany;
static size_t getCount() { return Counter < Widget > ::hMany(); }
};
class AnotherWidget : public Counter < AnotherWidget >
{
public :
static size_t getCount() { return Counter < AnotherWidget > ::hMany(); }
};


int main()
{
cout
<< sizeof (Widget) << endl;
cout
<< sizeof (AnotherWidget) << endl;

Widget a,b,c,d,e,f;
cout
<< f.getCount() << endl;
AnotherWidget x,y,z;
x
= z;
AnotherWidget h
= z;
cout
<< z.getCount() << endl;
return 0 ;
}

 

你可能感兴趣的:(object)