Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override a parent classes static variable

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....

like image 957
Mack Avatar asked Feb 01 '26 02:02

Mack


2 Answers

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.

like image 171
iammilind Avatar answered Feb 02 '26 15:02

iammilind


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.

like image 39
Mahesh Avatar answered Feb 02 '26 16:02

Mahesh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!