00:41

Как в С++ подсчитать количество созданных объектов? То есть, проще говоря, как узнать, сколько раз были созданы объекты класса A, и сколько раз объекты класса B?
Я разместил возможный вариант решения у себя, но мне не нравится, что мой вариант не работает для множественного наследования в общем случае.
Заранее спасибо.

Комментарии
14.03.2008 в 00:46

149ea694a792f3ad2caaf77077a0df58 Спорящая с богом
Статическое поле и инкремент в конструкторе. Вряд ли можно придумать более удобное решение.
14.03.2008 в 01:46

65 108 101 120 97 110 100 101 114
Караидель так и есть.
14.03.2008 в 10:02

Ну а если class B: public A {}; , тогда не годится инкремент в конструкторе, потому что для объектов вызываются конструкторы A() и B(). А если где-то есть множественное наследование, то вообще труба.
Спасибо. Буду думать еще.
14.03.2008 в 15:48

Появилась мысль для проверки наследования анализировать указатель, возвращаемый dynamic_cast. Но полноценного функционирования для множественного наследования пока все равно не получается.
Возможно, направление мыслей вообще выбрано неправильное. Люди, есть еще идеи?
14.03.2008 в 21:34

Мдя, с dynamic_cast это вообще перебор, и нафиг не нужно. Существенно облегчил конструкцию счетчика. И, наверное, с множественным наследованием биться бесполезно...
23.03.2008 в 12:46

Люди никогда не достигнут совершенства, пока будут оставаться людьми...
В чём проблема? Если у нас унаследован класс B от A то конструктор B имеет вид:

B(<...>;): A(<...>;), <...>{
<...>
}

Берём создаём абстрактный класс от которого наследуем все остальные. В абстрактном классе заводим статическую переменную и конструктор, но конструктор принимает ссылку на какую-то переменную и увеличивает её. Всё, после чего нужно лишь каждый раз при вызове конструктора нашего класса, передавать в конструктор базового нашу статическую переменную. При множественном наследовании можно передавать только один раз, но тогда нужно этот параметр в абстактном классе сделать необязательным ну и, например, увеличивать счётчик переменной абстрактного класса. Коннект?
24.03.2008 в 11:51

Полтора часа коллективных трудов, и да)) Коннект. Спасибо)
Получается, что нужно в каждом классе объявлять статическую переменную-счетчик и статический метод для считывания значения счетчика. И еще правильно вызвать конструктор счетчика. Работает, но достаточно громоздко прописывать.
У нас решение вроде покрасивее получилось. Если интересно — вот здесь.
24.03.2008 в 12:01

Уважаемый [revolver], вообще хотелось бы не просто объяснения, а примера на языке С++.
Попробовав написать код по авшему объяснению, получилось:
#include <iostream>

using namespace std;

class Counter {
static int m_CounterCount;
public:
Counter() { m_CounterCount++; }
Counter(int & Cnt) { Cnt++; }
virtual void Method() = 0;
};

class Base : public Counter {
static int m_BaseCount;
public:
Base(int & Cnt) : Counter(Cnt) { }
Base() : Counter(m_BaseCount) { }
static int Value(void) { return m_BaseCount; }
void Method() { };
};
int Base::m_BaseCount = 0;

class Derived1 : virtual public Base {
static int m_Derived1Count;
public:
Derived1(int & Cnt) : Base(Cnt) { }
Derived1() : Base(m_Derived1Count) { }
static int Value(void) { return m_Derived1Count; }
};
int Derived1::m_Derived1Count = 0;

class Derived2 : virtual public Base {
static int m_Derived2Count;
public:
Derived2(int & Cnt) : Base(Cnt) { }
Derived2() : Base(m_Derived2Count) { }
static int Value(void) { return m_Derived2Count; }
};
int Derived2::m_Derived2Count = 0;

class MultiDerived : virtual public Derived1, Derived2 {
static int m_MultiDerivedCount;
int tmp;
public:
MultiDerived(int & Cnt) : Base(Cnt), Derived1(tmp), Derived2(tmp) { }
MultiDerived() : Base(m_MultiDerivedCount), Derived1(tmp), Derived2(tmp) { }
static int Value(void) { return m_MultiDerivedCount; }
};
int MultiDerived::m_MultiDerivedCount = 0;

#define PRINT_COUNTOF(type) \
std::cout <
int main(void) {
PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);
cout < {
Derived1 dev1;
Derived2 dev2, dev3;
Base base, base2, base3;
MultiDerived mul, mul2, mul3, mul4;

PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);
cout < }
PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);

return 0;
}

Метод Method класса Counter, введён, чтобы сделать класс Counter абстрактным, чтобы максимально соответствовать вашим объяснениям.
Недостатком данного подхода является то, что деструктора не уменьшают счётчики, поэтому это получается тока подсчёт созданий объектов, но не их реальное количество.
24.03.2008 в 12:27

Извините, не учёл особесности HTML тегов, вот исправленный исходник:

#include <iostream>

using namespace std;

class Counter {
static int m_CounterCount;
public:
Counter() { m_CounterCount++; }
Counter(int & Cnt) { Cnt++; }
virtual void Method() = 0;
};

class Base : public Counter {
static int m_BaseCount;
public:
Base(int & Cnt) : Counter(Cnt) { }
Base() : Counter(m_BaseCount) { }
static int Value(void) { return m_BaseCount; }
void Method() { };
};
int Base::m_BaseCount = 0;

class Derived1 : virtual public Base {
static int m_Derived1Count;
public:
Derived1(int & Cnt) : Base(Cnt) { }
Derived1() : Base(m_Derived1Count) { }
static int Value(void) { return m_Derived1Count; }
};
int Derived1::m_Derived1Count = 0;

class Derived2 : virtual public Base {
static int m_Derived2Count;
public:
Derived2(int & Cnt) : Base(Cnt) { }
Derived2() : Base(m_Derived2Count) { }
static int Value(void) { return m_Derived2Count; }
};
int Derived2::m_Derived2Count = 0;

class MultiDerived : virtual public Derived1, Derived2 {
static int m_MultiDerivedCount;
int tmp;
public:
MultiDerived(int & Cnt) : Base(Cnt), Derived1(tmp), Derived2(tmp) { }
MultiDerived() : Base(m_MultiDerivedCount), Derived1(tmp), Derived2(tmp) { }
static int Value(void) { return m_MultiDerivedCount; }
};
int MultiDerived::m_MultiDerivedCount = 0;

#define PRINT_COUNTOF(type) \
std::cout << "Count of '" << #type << "':" << type::Value() << std::endl

int main(void) {
PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);
cout << "==================" << endl;
{
Derived1 dev1;
Derived2 dev2, dev3;
Base base, base2, base3;
MultiDerived mul, mul2, mul3, mul4;

PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);
cout << "==================" << endl;
}
PRINT_COUNTOF(Base);
PRINT_COUNTOF(Derived1);
PRINT_COUNTOF(Derived2);
PRINT_COUNTOF(MultiDerived);

return 0;
}



Да, и ещё, как-то это получается коряво, все эти навески на каждый производный класс, да и при этом надо знать полную иерархию классов, что не всегда возможно!