есть ли способ заставить все производные классы считать их экземпляры? Как (написать код на одном из C ++, C #, Java)?
Представьте, что у меня есть доступ к корневому классу (например, объекту), и каждый другой класс (прямо или косвенно) является производным от этого класса. То, что я хочу, это:
AnyDerivedClass.InstancesCount()
Проблема в том, что нужно отслеживать количество в статической переменной, но невозможно «внедрить» статическую переменную в производный класс из базового класса, это справедливо только для переменных-членов.
То есть я должен написать что-то вроде:
class object
{
private static int count = 0;
protected object() { ++count; }
protected ~object() { --count; }
public static InstancesCount() { return count; }
};
class derived : object
{
private static int count = 0;
public derived() { ++count; }
public ~derived() { --count; }
public static InstancesCount() { return count; }
}
Эта функциональность явно повторяется, и я не могу поместить ее в базовый класс.
Обратите внимание, что существует 2 способа вычисления: если имеется 7 экземпляров класса производного 1 и 8 экземпляров класса производного 2, то существует (а) 15 экземпляров объекта или (б) 0 экземпляров объекта. Мне все равно, какой из них, потому что я не могу сделать ни то, ни другое (используя достаточно практичные средства, например, представьте 100 классов, половина из которых находится в библиотеке, которую я не могу изменить).
Конечно, теоретически можно создать карту (некоторый идентификатор типа типа выполнения) => int count и использовать уродливый, медленный (основанный на времени выполнения) подход (по крайней мере, в C #, Java). ).
Конечно, если я могу модифицировать производные классы, я могу использовать копирование-вставку (ужасно), макрос (да, я знаю), миксины (не на этих языках) и т. Д. Но это по-прежнему ужасно.
Это специфическая проблема, но со мной несколько раз случалось, что я хотел бы иметь возможность "внедрить" статический член в производный класс для элегантного решения проблемы.
Помощь очень ценится.
РЕДАКТИРОВАТЬ: спасибо за хороший ответ, в C ++ возможно также использовать CRTP (Любопытно повторяющийся шаблон), но не в C # / Java (без множественного наследования). Конечно, нужно иметь доступ к производным классам и добавить этот базовый класс, поэтому вопрос остается (если нет другого пути, это выглядит лучше).
РЕДАКТИРОВАТЬ 2: выглядит невозможно с текущими языками. Статическая часть каждого класса не наследуется (и это правильно), но нет наследующего синглтона, связанного с каждым классом, поэтому проблемы такого рода не могут быть решены так элегантно.
Чтобы проиллюстрировать это, взгляните на следующий код: обычные и статические члены являются текущей функцией языков ООП, члены-одиночки (или каковы бы ни были слова) являются моим предложением / желанием:
class Base
{
static int sMemberBase;
int memberBase;
//my wish (note that virtual for methods is allowed!):
singleton int singletonMemberBase;
};
class Derived : Base
{
static int sMemberDerived;
int memberDerived;
//my wish (note that virtual for methods is allowed!):
singleton int singletonMemberDerived;
};
//taken apart: (note: XYZStatic classes do not derive)
class Base { int memberBase; }
class BaseStatic { int sMemberBase; } BaseStaticInstance;
class Derived : Base { int memberDerived; }
class DerivedStatic { int sMemberDerived; } BaseStaticInstance;
//note: Derived::sMemberBase is compile-time changed to Base::sMemberBase
//my wish: (note inheritance!)
class BaseSingleton { int singletonMemberBase; } BaseSingletonInstance;
class DerivedSingleton : BaseSingleton { int singletonMemberDerived; } DerivedSingletonInstance;
Если бы что-то подобное присутствовало в языке, решение моего вопроса было бы простым и элегантным:
//with singleton members, I could write counter like this:
class object
{
singleton int count;
object() { ++count; }
~object() { --count; }
};