Re: How to make every derived class to return a different int
Stefano Sabatini wrote:
[snip]
Yes, I tried it and it is indeed what I need. Only what I also need
would be a static method which returns the total number of objects
already registered.
Objects or classes?
Assuming classes, this poses an interesting problem. Here are two attempts:
a)
class reg_base {
protected:
static
unsigned int &
the_count ( void ) {
static unsigned int c = 0;
return ( c );
}
static
unsigned int count ( void ) {
return ( the_count() ++ );
}
public:
static
unsigned int num_classes ( void ) {
return ( the_count() );
}
virtual
unsigned int get_id ( void ) const = 0;
virtual
~reg_base ( void ) {}
};
template < typename D >
class reg : public reg_base {
static unsigned int const the_id;
public:
unsigned int get_id ( void ) const {
return ( the_id );
}
static
unsigned int id ( void ) {
return ( the_id );
}
virtual
~reg ( void ) {}
};
template < typename D >
unsigned int const reg<D>::the_id = reg<D>::reg_base::count();
struct X : public reg<X> {};
struct Y : public reg<Y> {};
struct Z : public reg<Z> {};
#include <iostream>
int main ( void ) {
std::cout << "Classes: " << reg_base::num_classes() << '\n';
X x;
Y y1;
Y y2;
reg_base * px = new X ();
reg_base * py = new Y ();
std::cout << "X " << x.get_id() << '\n';
std::cout << "Y " << y1.get_id() << '\n';
std::cout << "Y " << y2.get_id() << '\n';
std::cout << "X " << px->get_id() << '\n';
std::cout << "Y " << py->get_id() << '\n';
std::cout << "X " << X::id() << '\n';
std::cout << "Y " << Y::id() << '\n';
delete ( px );
delete ( py );
}
This one does not count the class Z. Honestly, I don't know the reason.
b)
class reg_base {
protected:
static
unsigned int &
the_count ( void ) {
static unsigned int c = 0;
return ( c );
}
static
unsigned int count ( void ) {
return ( the_count() ++ );
}
public:
static
unsigned int num_classes ( void ) {
return ( the_count() );
}
virtual
unsigned int get_id ( void ) const = 0;
virtual
~reg_base ( void ) {}
};
template < typename D >
class reg : public reg_base {
static
unsigned int & the_id ( void ) {
static unsigned int dummy = 0;
return ( dummy );
}
struct do_register {
do_register ( void ) {
the_id() = reg<D>::reg_base::count();
}
};
public:
reg ( void ) {
static do_register dummy;
}
unsigned int get_id ( void ) const {
return ( the_id() );
}
static
unsigned int id ( void ) {
return ( the_id() );
}
virtual
~reg ( void ) {}
};
struct X : public reg<X> {};
struct Y : public reg<Y> {};
struct Z : public reg<Z> {};
#include <iostream>
int main ( void ) {
std::cout << "Classes: " << reg_base::num_classes() << '\n';
X x;
std::cout << "Classes: " << reg_base::num_classes() << '\n';
Y y1;
Y y2;
std::cout << "Classes: " << reg_base::num_classes() << '\n';
Z z;
std::cout << "Classes: " << reg_base::num_classes() << '\n';
reg_base * px = new X ();
reg_base * py = new Y ();
std::cout << "X " << x.get_id() << '\n';
std::cout << "Y " << y1.get_id() << '\n';
std::cout << "Y " << y2.get_id() << '\n';
std::cout << "X " << px->get_id() << '\n';
std::cout << "Y " << py->get_id() << '\n';
std::cout << "X " << X::id() << '\n';
std::cout << "Y " << Y::id() << '\n';
delete ( px );
delete ( py );
std::cout << "Classes: " << reg_base::num_classes() << '\n';
}
This one counts each class, once the first object of that class has been
constructed.
I don't know, which semantics you actually need.
Best
Kai-Uwe Bux