How do you implement this Python idiom in C++

Pierre Barbier de Reuille p.barbierdereuille at free.fr
Fri Jul 28 13:07:41 EDT 2006


alainpoint at yahoo.fr wrote:
> Rob Williscroft wrote:
> 
>> If this is more than idle curiosity I strongly suggest you post
>> a version of the python code you need to translate to C++.
> 
> For the moment this is just healthy curiosity but i will still post the
> code i would like to see translated:
> 
> class Parent:
> 	count=0
> 	def __init__(self):
> 		self.__class__.count +=1
> 	@classmethod
> 	def getcount(cls):
> 		return cls.count
> 
> class Child(Parent):
> 	count=0 # replace this line by a 'pass'  statement if you don't want
> to reinitialise the count
> 
> a=Parent()
> b=Parent()
> print Parent.getcount()  # you get 2
> c=Child()
> d=Child()
> e=Child()
> print Child.getcount() # you get 3 (you could get 5 if you don't
> reinitialise the count)
> 
> This is as simple as it can get. I just derive from Parent and i get my
> proper count (added to my parent's if i wish so).
> I wish i could achieve such a code purity in C++.

Well, I hope you understand that this code "purity" is possible only
because of the *dynamic* lookup of the variable name ... Thus, the same
function, once compiled, will be able to determine, at runtime, where
the current variable lies ... At the same time, tries, in Python, to
achieve the count of *all* the instances of a class, meaning that you want :

a = Parent()
b = Child()
c = Parent()
d = Child()
print Child.getcount() # 2
print Parent.getcount() # 4

That time, the automatic name lookup will come in the way as you cannot
have two "count" variables accessible from the same class.
For C++ the problem is inverse, you have a way to obtain the second
thing (using templates or macro), but the first is harder.

Pierre

PS: here is my solution in C++


#include <iostream>
using namespace std;

template <class T>
struct Counted
{
  Counted() { ++count; }
  Counted( Counted const& ) { ++count; }
  virtual ~Counted() { --count; }
  static size_t getCount() { return count; }
protected:
  static size_t count;
};

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

struct cA : public Counted<cA>
{
  int a;
};

struct cB : public Counted<cB>, public cA
{
  // Needed to be sure of which getCount is called in cB
  using Counted<cB>::getCount;
};

int main()
{
  cA a,b,c;
  cB d,e,f;
  a.a = 1;
  b.a = 1;
  c.a = 1;
  d.a = 1;
  e.a = 1;
  f.a = 1;
    {
    cA g;
    g.a = 1;
    cout << "#cA = " << cA::getCount() << endl; // 7
    cout << "#cB = " << cB::getCount() << endl; // 3
    }
  cout << "#cA = " << cA::getCount() << endl; // 6
  cout << "#cB = " << cB::getCount() << endl; // 3
  return 0;
}



More information about the Python-list mailing list