计数类实例为每个派生类 [英] count class instances for every derived class

查看:128
本文介绍了计数类实例为每个派生类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有什么办法,使所有派生类指望它们的实例?如何(在C ++,C#,Java的一个写代码)?



想象我有访问根类(如对象),和所有其他类(直接或间接)从这个类派生。我要的是:



  AnyDerivedClass.InstancesCount()

问题是,必须保持跟踪在静态变量计数,但它不可能注入静态变量成从基类派生的类,这仅适用于成员变量。
也就是说,我必须写这样的:

 类对象
{
私人静态诠释计数= 0;
保护对象(){++计数; }
保护对象〜(){--count; }
公共静态InstancesCount(){返回计数; }
};

类派生:对象
{
私有静态诠释计数= 0;
公共派生(){++计数; }
公共〜衍生(){--count; }
公共静态InstancesCount(){返回计数; }
}

这功能显然是重复的,我不能把它的基类。
注有2种方式计算:如果有类derived1 7实例和类Derived2的8个实例,它是(a)或对象的15个实例(B)的对象0实例。我不在乎是哪一个,因为我不能这样做既不(使用合理可行的手段,如想象100班,其中一半是在图书馆我不能修改)。



当然,在理论上是可能的创造(一些运行型类型标识符)=>为int的地图计数,并用丑陋的,缓慢的,(运行时类型)为基础的方法(至少在C#,Java的)



当然,如果我可以修改派生类,我可以使用复制粘贴(可怕的),宏(是的,我知道),混入(而不是用这些语言)等等。但是,这仍然是真正的丑陋。



这是具体的问题,但它发生在我几次,我希望能够注入静。成员为派生类中完美地解决问题。



帮助非常感谢



编辑:谢谢你很好的答案,在C ++中它可能是使用CRTP(奇怪的是经常性模板模式)为好,但不是在C#/ Java的(无多重继承)。当然,人们必须能够访问派生类,并添加这个基类,所以问题是(如果没有其他办法,这看起来最好)。



编辑2 :当前语言看起来是不可能的。每一类的静态部分没有继承(这是正确的),但与每一个类相关联没有继承单身,所以这些类型的问题不能这么优雅的解决。
。要说明的事情,看看下面的代码:普通会员和静态成员是当前OOP语言功能,单(或任何字会)成员都是我的建议/愿望:

  Base类
{
静态INT sMemberBase;
INT memberBase;

//我的愿望(请注意,虚拟的方法是允许的!):
单INT singletonMemberBase;
};
类派生:基本
{
静态INT sMemberDerived;
INT memberDerived;

//我的愿望(请注意,虚拟的方法是允许的!):
单INT singletonMemberDerived;
};

//拆开:(注:XYZStatic类不派生)
类基地{INT memberBase; }
类BaseStatic {INT sMemberBase; } BaseStaticInstance;
类派生:基{诠释memberDerived; }
类DerivedStatic {诠释sMemberDerived; } BaseStaticInstance;
//注:衍生:: sMemberBase是编译时改变为基地:: sMemberBase

//我的愿望:(!注继承)
类BaseSingleton {INT singletonMemberBase; } BaseSingletonInstance;
类DerivedSingleton:BaseSingleton {INT singletonMemberDerived; } DerivedSingletonInstance;

如果这样的事情会出现在语言,我的问题的解决办法是简单而优雅的:

  //与单身的成员,我可以写柜台像这样:
类对象
{
单诠释计数;
对象(){++计数; }
〜对象(){--count; }
};


解决方案

在C ++中,你可以用一个模板库做类。基本上它的的一个mixin,所以它仍然需要每一个类从混入继承商合作:

  //警告:不是线程安全
:模板LT; typename的T>
类instance_counter {
公众:
静态为size_t InstancesCount(){返回计数(); }
instance_counter(){计数()+ = 1; }
instance_counter(常量instance_counter&安培;){计数()+ = 1; }
//罕见的情况下,我们并不需要实现拷贝赋值操作符。
保护:
〜instance_counter(){COUNT() - = 1; }
私人:
静态为size_t和放大器;计数{
静态为size_t计数= 0;
返回柜台;
}
};

类my_class:公共instance_counter< my_class> {};



由于每类使用模板具有的不同的的基类,它有一个的不同的计数功能,因此静态变量的不同副本计数



作为一个模板参数被称为CRTP派生类从实例化的模板类继承的把戏。


is there any way to make all derived classes count their instances?How (write code in one of C++, C#, Java)?

Imagine I've got access to the root class (e.g. object), and every other class is (directly or indirectly) derived from this class. What I want is:

AnyDerivedClass.InstancesCount()

Problem is, one must keep track of count in static variable, but it is not possible to "inject" static variable into derived class from base class, this holds only for member variables. That is, I have to write something like:

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; }
}

This functionality is obviously repeated, and I cannot put it in base class. Note there are 2 ways of calculating: that if there are 7 instances of class derived1 and 8 instances of class derived2, there are (a) 15 instances of object or (b) 0 instances of object. I don't care which one, because I can't do neither (using reasonably practical means, e.g. imagine 100 classes, half of which are in library I cannot modify).

Of course, in theory it is possible to create map of (some run-type type identifier) => int count, and use ugly, slow, (run-time type)-based approach (at least in C#, Java).

Of course, if I can modify derived classes, I can use copy-paste (awful), macro (yeah I know), mixins (not in these languages) etc. But that is still real ugly.

This is specific problem, but It happened to me several times, that I'd like to be able to "inject" static member into derived class to solve problem elegantly.

Help much appreciated.

EDIT: thanks for good answer, in C++ it is possibly to use CRTP (Curiously recurring template pattern) as well, but not in C#/Java (no multiple inheritance). Of course, one must have access to derived classes and add this base class, so question remains (in case there is no other way, this looks best).

EDIT 2: looks impossible with current languages. static part of every class is not inheriting (and that's right), but there is no inheriting singleton associated with every class, so these kinds of problems cannot be solved so elegantly. To illustrate things, look at the following code: normal members and static members are current OOP languages feature, "singleton" (or whatever word would be) members are my suggestion/desire:

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;

If anything like that would be present in language, solution for my question would be simple and elegant:

//with singleton members, I could write counter like this:
class object
{
    singleton int count;
    object() { ++count; }
    ~object() { --count; }
};

解决方案

In C++, you can do it with a template base class. Basically it is a mixin, so it does still require each class to co-operate by inheriting from the mixin:

// warning: not thread-safe
template <typename T>
class instance_counter {
  public:
    static size_t InstancesCount() { return count(); }
    instance_counter() { count() += 1; }
    instance_counter(const instance_counter&) { count() += 1; }
    // rare case where we don't need to implement the copy assignment operator.
  protected:
    ~instance_counter() { count() -= 1; }
  private:
    static size_t &count {
        static size_t counter = 0;
        return counter;
    }
};

class my_class: public instance_counter<my_class> {};

Since each class using the template has a different base class, it has a different count function and hence a different copy of the static variable counter.

The trick of inheriting from a template class that's instantiated using the derived class as a template parameter is called CRTP.

这篇关于计数类实例为每个派生类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆