How do you implement this Python idiom in C++
alainpoint at yahoo.fr
alainpoint at yahoo.fr
Sun Jul 30 13:21:09 EDT 2006
Pierre Barbier de Reuille wrote:
> 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;
> }
I thank you for your response. The equivalent of your solution is
posted hereunder:
class cA(object):
count=0
def __init__(self):
self.__class__.count +=1
@classmethod
def getcount(cls):
return cls.count
def __del__(self):
self.__class__.count -=1
class cB(cA):
count=0
def __init__(self):
super(cB,self).__init__()
for klass in self.__class__.__bases__:
klass.count +=1
a=cA() ; b=cA(); c= cA()
d=cB() ; e=cB(); f= cB()
a.a=1;b.a=1;c.a=1;d.a=1;e.a=1;f.a=1
g=cA()
g.a=1
print '#cA=',cA.getcount() # 7
print '#cB=',cB.getcount() # 3
del g
print '#cA=',cA.getcount() # 6
print '#cB=',cB.getcount() # 3
There is nothing impossible in Python ;-)
Alain
More information about the Python-list
mailing list