Пытался сам решить — но не осилил, хотя с mpl знаком.
Задачу привожу упрощённо. Есть неопределённое кол-во классов, предком которых является один шаблонный класс 'unit'.
template< typename T>
class unit
{
}
////
class A: public unit<A>
{
}
////
class B : public unit<B>
{
}
////
class C : public unit<C>
{
}
/////
....
////
Вопрос: как и в каком виде мне накопить информацию, для каких типов класс unit был проинстационирован? То есть — в разрезе примера, как мне накопить типы A,B,C,...
Хотел в результате получить кортеж с этими типами, или какой нибудь boost::fusion::vector<A,B,C,..> , но ума не хватает.
Спасибо.
ЗЫ Данная конструкция нужна мне для контроля за кол-вом экземпляров созданных и уничтоженых экземляров классов A,B,C ... в плане борьбы с утечками.
Здравствуйте, Haccel, Вы писали:
H>Пытался сам решить — но не осилил, хотя с mpl знаком.
H>Задачу привожу упрощённо. Есть неопределённое кол-во классов, предком которых является один шаблонный класс 'unit'.
...
H>Вопрос: как и в каком виде мне накопить информацию, для каких типов класс unit был проинстационирован? То есть — в разрезе примера, как мне накопить типы A,B,C,...
H>Хотел в результате получить кортеж с этими типами, или какой нибудь boost::fusion::vector<A,B,C,..> , но ума не хватает.
H>Спасибо.
H>ЗЫ Данная конструкция нужна мне для контроля за кол-вом экземпляров созданных и уничтоженых экземляров классов A,B,C ... в плане борьбы с утечками.
Кортеж врядли получится,... Но для заявленой цели он, кажется, и не нужен.
Вообще регистрация типов может быть выполменна так:
template <class T>
struct unit
{
static const i_meta_information& m_meta;
virtual const i_meta_information& meta() const { return m_meta; } // virtual нужен, иначе метод может быть выброшен как не использемый, а с ним и статическая переменная ....
};
template <class T>
const i_meta_information& unit<T>::m_meta = register_meta_information<T>();
Однако, в твоем случае, не нужна даже регистрация типов.
Например:
template <class T>
struct life_time_controller
{
typedef life_time_controller me;
life_time_controller() : id(new_id()) { collection().insert(this); }
life_time_controller(const me&) : id(new_id()) { collection().insert(this); }
~life_time_controller() { collection().erase (this); }
const int id;
private:
static int new_id()
{
static int ret=0;
++ret;
return ret; // set conditional break point there
}
struct collection_type
{
boost::unordered_set<void*> living_objects;
~collection_type()
{
if(!living_objects.empty())
{
std::cerr << "type: " << typeid(T).name()
<< " living_objects: " << living_objects.size()
<< " ids: ";
BOOST_FOREACH(void*ptr, living_objects)
std::cerr << static_cast<life_time_controller<T>*>(ptr)->id << " ";
std::cerr << std::endl;
}
}
};
static boost::unordered_set<void*>& collection()
{
static collection_type ret;
return ret.living_objects;
}
};
template <class T>
struct unit : life_time_controller<T> //, ...
{
// ...
};
struct A : unit<A> {};
struct B : unit<B> {};
struct C : unit<C> {};
int main(int argc, char *argv[])
{
new A();
new B[3]();
return 0;
}
type: struct B living_objects: 3 ids: 3 1 2
type: struct A living_objects: 1 ids: 1
Здравствуйте, Chorkov, Вы писали:
C>Здравствуйте, Haccel, Вы писали:
H>>Пытался сам решить — но не осилил, хотя с mpl знаком.
H>>Задачу привожу упрощённо. Есть неопределённое кол-во классов, предком которых является один шаблонный класс 'unit'.
C>...
H>>Вопрос: как и в каком виде мне накопить информацию, для каких типов класс unit был проинстационирован? То есть — в разрезе примера, как мне накопить типы A,B,C,...
H>>Хотел в результате получить кортеж с этими типами, или какой нибудь boost::fusion::vector<A,B,C,..> , но ума не хватает.
H>>Спасибо.
H>>ЗЫ Данная конструкция нужна мне для контроля за кол-вом экземпляров созданных и уничтоженых экземляров классов A,B,C ... в плане борьбы с утечками.
C>Кортеж врядли получится,... Но для заявленой цели он, кажется, и не нужен.
C>Вообще регистрация типов может быть выполменна так:
C>C>template <class T>
C>struct unit
C>{
C> static const i_meta_information& m_meta;
C> virtual const i_meta_information& meta() const { return m_meta; } // virtual нужен, иначе метод может быть выброшен как не использемый, а с ним и статическая переменная ....
C>};
C>template <class T>
C>const i_meta_information& unit<T>::m_meta = register_meta_information<T>();
C>
C>Однако, в твоем случае, не нужна даже регистрация типов.
C>Например:
C>
C>template <class T>
C>struct life_time_controller
C>{
C> typedef life_time_controller me;
C> life_time_controller() : id(new_id()) { collection().insert(this); }
C> life_time_controller(const me&) : id(new_id()) { collection().insert(this); }
C> ~life_time_controller() { collection().erase (this); }
C> const int id;
C>private:
C> static int new_id()
C> {
C> static int ret=0;
C> ++ret;
C> return ret; // set conditional break point there
C> }
C> struct collection_type
C> {
C> boost::unordered_set<void*> living_objects;
C> ~collection_type()
C> {
C> if(!living_objects.empty())
C> {
C> std::cerr << "type: " << typeid(T).name()
C> << " living_objects: " << living_objects.size()
C> << " ids: ";
C> BOOST_FOREACH(void*ptr, living_objects)
C> std::cerr << static_cast<life_time_controller<T>*>(ptr)->id << " ";
C> std::cerr << std::endl;
C> }
C> }
C> };
C> static boost::unordered_set<void*>& collection()
C> {
C> static collection_type ret;
C> return ret.living_objects;
C> }
C>};
C>
C>C>template <class T>
C>struct unit : life_time_controller<T> //, ...
C>{
C> // ...
C>};
C>struct A : unit<A> {};
C>struct B : unit<B> {};
C>struct C : unit<C> {};
C>int main(int argc, char *argv[])
C>{
C> new A();
C> new B[3]();
C> return 0;
C>}
C>
C>C>type: struct B living_objects: 3 ids: 3 1 2
C>type: struct A living_objects: 1 ids: 1
C>
Слов нет — мой поклон до земли. Перевариваю.
Здравствуйте, Chorkov, Вы писали:
C>Здравствуйте, Haccel, Вы писали:
H>>Пытался сам решить — но не осилил, хотя с mpl знаком.
H>>Задачу привожу упрощённо. Есть неопределённое кол-во классов, предком которых является один шаблонный класс 'unit'.
C>...
H>>Вопрос: как и в каком виде мне накопить информацию, для каких типов класс unit был проинстационирован? То есть — в разрезе примера, как мне накопить типы A,B,C,...
H>>Хотел в результате получить кортеж с этими типами, или какой нибудь boost::fusion::vector<A,B,C,..> , но ума не хватает.
H>>Спасибо.
H>>ЗЫ Данная конструкция нужна мне для контроля за кол-вом экземпляров созданных и уничтоженых экземляров классов A,B,C ... в плане борьбы с утечками.
C>Кортеж врядли получится,... Но для заявленой цели он, кажется, и не нужен.
C>Вообще регистрация типов может быть выполменна так:
C>C>template <class T>
C>struct unit
C>{
C> static const i_meta_information& m_meta;
C> virtual const i_meta_information& meta() const { return m_meta; } // virtual нужен, иначе метод может быть выброшен как не использемый, а с ним и статическая переменная ....
C>};
C>template <class T>
C>const i_meta_information& unit<T>::m_meta = register_meta_information<T>();
C>
C>Однако, в твоем случае, не нужна даже регистрация типов.
C>Например:
C>
C>template <class T>
C>struct life_time_controller
C>{
C> typedef life_time_controller me;
C> life_time_controller() : id(new_id()) { collection().insert(this); }
C> life_time_controller(const me&) : id(new_id()) { collection().insert(this); }
C> ~life_time_controller() { collection().erase (this); }
C> const int id;
C>private:
C> static int new_id()
C> {
C> static int ret=0;
C> ++ret;
C> return ret; // set conditional break point there
C> }
C> struct collection_type
C> {
C> boost::unordered_set<void*> living_objects;
C> ~collection_type()
C> {
C> if(!living_objects.empty())
C> {
C> std::cerr << "type: " << typeid(T).name()
C> << " living_objects: " << living_objects.size()
C> << " ids: ";
C> BOOST_FOREACH(void*ptr, living_objects)
C> std::cerr << static_cast<life_time_controller<T>*>(ptr)->id << " ";
C> std::cerr << std::endl;
C> }
C> }
C> };
C> static boost::unordered_set<void*>& collection()
C> {
C> static collection_type ret;
C> return ret.living_objects;
C> }
C>};
C>
C>C>template <class T>
C>struct unit : life_time_controller<T> //, ...
C>{
C> // ...
C>};
C>struct A : unit<A> {};
C>struct B : unit<B> {};
C>struct C : unit<C> {};
C>int main(int argc, char *argv[])
C>{
C> new A();
C> new B[3]();
C> return 0;
C>}
C>
C>C>type: struct B living_objects: 3 ids: 3 1 2
C>type: struct A living_objects: 1 ids: 1
C>
Про вариант без регистрации думал изначально, но основе typeinfo , но отпугнуло повсеместное инклюженье typeinfo.h в весь проект, ведь так или иначе, заголовочный файл с классом unit придётся инклюдить везде и в .cpp это перенести — нет вариантов. Проект пишется на QT , а оно вроде неодбряет использование rtti, хотя я могу путаться в этих вопросах, прошу разъяснить, если не сложно. Тема с регистрацией типов больше нравится, так как она чище, но вы к сожалению плохо её раскрыли ( если можно, добавьте в реализацию пару строк, что бы было наглядно — где конкретно копить типы ). По мне оба варианта интересны, и буду в проектах применять обе (конечно не одновременно).