如何覆盖父类静态变量

发布于 2024-11-02 14:25:27 字数 3326 浏览 2 评论 0原文

如何覆盖父类静态变量。

因此,

class DatabaseItem
{
   static int instanceCount;

   DatabaseItem()
   {
     instanceCount++;
   }
};

如果我有 2 个从 DatabaseItem 继承的类,我希望每个类记录仅存在其类的多少个实例。我该怎么做?

所以:

class Person : public DatabaseItem
{
  // how do I make sure when I make the call  int numOfpeople = Person::instanceCount;
  // that I only get the number of people objects that exist & not all the DatabaseItem
  // objects that exist?
};

class FoodItem : public DatabaseItem
{
  // how do I make sure when I make the call  int numOffoodItems = FoodItem::instanceCount;
  // that I only get the number of FoodItem objects that exist & not all the DatabaseItem
  // objects that exist?
};

编辑回应评论

是的,但是,上面只是一个例子,如果我这样做,那么我有很多重复的代码......

所以:

    class DatabaseItem
{
    public:
        static unsigned int instanceCount;
        static Vector <unsigned int> usedIDs;

        unsigned int ID;

        DatabaseItem()
        {
            ID = nextAvailableID();
            usedIDs.add( ID );
            DatabaseItem::instanceCount++;
        }

        DatabaseItem( unsigned int nID )
        {
            if ( isIDFree( nID ) )
            {
                ID = nID;
            }
            else ID = nextAvailableID();

            usedIDs.add( ID );
            DatabaseItem::instanceCount++;
        }

        bool isIDFree( unsigned int nID )
        {
            // This is pretty slow to check EVERY element

            for (int i=0; i<usedIDs.size(); i++)
            {
                if (usedIDs[i] == nID)
                {
                    return false;
                }
            }

            return true;
        }

        unsigned int nextAvailableID()
        {
            unsigned int nID = 0;

            while ( true )
            {
                if ( isIDFree( ID ) )
                {
                    return nID;
                }
                else nID++;
            }
        }
};


class Person    {
    public:
        static unsigned int instanceCount;
        static Vector <unsigned int> usedIDs;

        unsigned int ID;

        Person()
        {
            ID = nextAvailableID();
            usedIDs.add( ID );
            Person::instanceCount++;
        }

        Person( unsigned int nID )
        {
            if ( isIDFree( nID ) )
            {
                ID = nID;
            }
            else ID = nextAvailableID();

            usedIDs.add( ID );
            Person::instanceCount++;
        }

        bool isIDFree( unsigned int nID )
        {
            // This is pretty slow to check EVERY element

            for (int i=0; i<usedIDs.size(); i++)
            {
                if (usedIDs[i] == nID)
                {
                    return false;
                }
            }

            return true;
        }

        unsigned int nextAvailableID()
        {
            unsigned int nID = 0;

            while ( true )
            {
                if ( isIDFree( ID ) )
                {
                    return nID;
                }
                else nID++;
            }
        }
};

..然后我必须重写相同的代码对于 FoodItem、coffeeRun...

How to override a parent classes static variable.

So I have the parent class

class DatabaseItem
{
   static int instanceCount;

   DatabaseItem()
   {
     instanceCount++;
   }
};

if I have 2 classes that inherit from DatabaseItem, I want each class to record how many instances of their class only exist. How do I do this?

So:

class Person : public DatabaseItem
{
  // how do I make sure when I make the call  int numOfpeople = Person::instanceCount;
  // that I only get the number of people objects that exist & not all the DatabaseItem
  // objects that exist?
};

class FoodItem : public DatabaseItem
{
  // how do I make sure when I make the call  int numOffoodItems = FoodItem::instanceCount;
  // that I only get the number of FoodItem objects that exist & not all the DatabaseItem
  // objects that exist?
};

EDIT In response to comments

Yeah but, the above is just an example, if I do this then I have alot of repeating code...

So:

    class DatabaseItem
{
    public:
        static unsigned int instanceCount;
        static Vector <unsigned int> usedIDs;

        unsigned int ID;

        DatabaseItem()
        {
            ID = nextAvailableID();
            usedIDs.add( ID );
            DatabaseItem::instanceCount++;
        }

        DatabaseItem( unsigned int nID )
        {
            if ( isIDFree( nID ) )
            {
                ID = nID;
            }
            else ID = nextAvailableID();

            usedIDs.add( ID );
            DatabaseItem::instanceCount++;
        }

        bool isIDFree( unsigned int nID )
        {
            // This is pretty slow to check EVERY element

            for (int i=0; i<usedIDs.size(); i++)
            {
                if (usedIDs[i] == nID)
                {
                    return false;
                }
            }

            return true;
        }

        unsigned int nextAvailableID()
        {
            unsigned int nID = 0;

            while ( true )
            {
                if ( isIDFree( ID ) )
                {
                    return nID;
                }
                else nID++;
            }
        }
};


class Person    {
    public:
        static unsigned int instanceCount;
        static Vector <unsigned int> usedIDs;

        unsigned int ID;

        Person()
        {
            ID = nextAvailableID();
            usedIDs.add( ID );
            Person::instanceCount++;
        }

        Person( unsigned int nID )
        {
            if ( isIDFree( nID ) )
            {
                ID = nID;
            }
            else ID = nextAvailableID();

            usedIDs.add( ID );
            Person::instanceCount++;
        }

        bool isIDFree( unsigned int nID )
        {
            // This is pretty slow to check EVERY element

            for (int i=0; i<usedIDs.size(); i++)
            {
                if (usedIDs[i] == nID)
                {
                    return false;
                }
            }

            return true;
        }

        unsigned int nextAvailableID()
        {
            unsigned int nID = 0;

            while ( true )
            {
                if ( isIDFree( ID ) )
                {
                    return nID;
                }
                else nID++;
            }
        }
};

.. then I have to rewrite the same code for FoodItem, coffeeRun....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光匆匆的小流年 2024-11-09 14:25:27

使用模板可以解决在每个构造函数等中更新实例计数的所有此类问题。

template<class T>
struct Instance
{
  static unsigned int count;
  Instance () { count ++; }
  Instance (const Instance& o) { count ++; }
};
template<class T>
unsigned int Instance<T>::count = 0;

现在这个模板可以由任何类继承,您需要对其实例进行计数:

class DatabaseItem : public Instance<DatabaseItem> {};
class Person : public DatabaseItem, Instance<Person> {};
class FoodItem : public DatabaseItem, Instance<FoodItem> {};

就是这样!

每当声明一个类对象时,它就会完成它的工作。它可以按如下方式使用:

DatabaseItem *pD = new DatabaseItem[5];
Person obj[10];
cout<<Instance<DatabaseItem>::count<<endl;  // 5 + 10 = 15
cout<<Instance<Person>::count<<endl;        // 10

您不必在任何地方更新计数。

Use templates to get away with all such problems of updating instance count in every constructor etc.

template<class T>
struct Instance
{
  static unsigned int count;
  Instance () { count ++; }
  Instance (const Instance& o) { count ++; }
};
template<class T>
unsigned int Instance<T>::count = 0;

Now this template can be inherited by any of the classes, which you need to get counted for their instances:

class DatabaseItem : public Instance<DatabaseItem> {};
class Person : public DatabaseItem, Instance<Person> {};
class FoodItem : public DatabaseItem, Instance<FoodItem> {};

That's it!

Whenever a class object is declared, it will do its job. It can be used as following:

DatabaseItem *pD = new DatabaseItem[5];
Person obj[10];
cout<<Instance<DatabaseItem>::count<<endl;  // 5 + 10 = 15
cout<<Instance<Person>::count<<endl;        // 10

You don't have to update count anywhere.

月野兔 2024-11-09 14:25:27

我认为不可能在基类中拥有静态变量并从中得知每种类型存在多少个派生类实例。相反,在每个类中都有一个静态类变量,该变量在构造函数中递增。

class Person : public DatabaseItem
{
     static int numPersonItems ;
     Person()
     {
         ++numPersonItems ;
     }
};

int DatabaseItem::numPersonItems = 0 ;

numPersonItemsPerson 实例的数量。对于 FoodItem 类也可以进行类似的操作。

I think it is not possible to have a static variable in the base class and tell from it how many derived class instances of each type are present. Instead, have a static class variable in each class that gets incremented in the constructor.

class Person : public DatabaseItem
{
     static int numPersonItems ;
     Person()
     {
         ++numPersonItems ;
     }
};

int DatabaseItem::numPersonItems = 0 ;

numPersonItems is the number of Person instances. Similarly can be done for the FoodItem class too.

暖树树初阳… 2024-11-09 14:25:27

鉴于您不能依赖基类构造函数中的虚拟分派,您需要直接向其提供静态信息作为参数,或者向其提供派生类,以便它可以查询静态信息本身。后者如下图所示

struct Base { 
    //provide whatever actual interface you need your type to have here
    virtual ~Base();
};

template<typename Derived>
struct Intermediate : Base {
    Intermediate() {
        Derived::var++;  //doesn't rely on polymorphism so ok in constructor
    }
};

struct Derived : Intermediate<Derived> {
    static int var;
};

,但是,鉴于您的具体用例,我倾向于根本不这样做,并且要么让基类将唯一 ID 分散到所有实例(无论类型如何),要么将 ID 创建移到单独的类中/method 直接,并查询它的唯一标识符:

template<typename T>
struct UniqueID { 
    static some64bitIntType GetID(); //possibly non-static, lots of ways to handle this
};

struct Object {
    some64bitIntType ID;
    Object() : ID(UniqueID<Object>::GetID()) { }
};

或者类似的东西。就我个人而言,我倾向于不费心将 ID 释放回来以供重复使用。这是大量的额外工作,几乎没有实际收益,除非您试图将自己限制在相对较少的实例数量。

Given that you can't rely on virtual dispatch in a base class constructor, you need to either provide the static information directly to it as a parameter, or provide the derived class to it so it can query the static information itself. The latter is illustrated below

struct Base { 
    //provide whatever actual interface you need your type to have here
    virtual ~Base();
};

template<typename Derived>
struct Intermediate : Base {
    Intermediate() {
        Derived::var++;  //doesn't rely on polymorphism so ok in constructor
    }
};

struct Derived : Intermediate<Derived> {
    static int var;
};

Given your specific use case, I would be inclined to not do this at all, however, and either have the base class disperse unique IDs to all instances, regardless of type, or move the ID creation into a separate class/method outright, and query it for a unique identifier:

template<typename T>
struct UniqueID { 
    static some64bitIntType GetID(); //possibly non-static, lots of ways to handle this
};

struct Object {
    some64bitIntType ID;
    Object() : ID(UniqueID<Object>::GetID()) { }
};

Or something along those lines. Personally, I'd be inclined not to bother with releasing IDs back to be reused. Its a lot of extra work, with little practical gain unless you're trying to limit yourself to a relatively small number of instances.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文