Home > Mobile >  Get number of active class instances
Get number of active class instances

Time:05-29

I need to get a number of created and the number of active class instances.

#include <iostream>
#include <stdexcept>
class Set {
  double value;
  int created = 0;
  int active = 0;
public:
  Set();
  Set(double num);
  static int NumberOfCreated();
  static int NumberOfActive();
};
Set::Set() : value(0) {}
Set::Set(double num) : value(num) {
  created  ;
  active  ;
}
int Set::NumberOfCreated() { return created; }
int Set::NumberOfActive() { return active; }
int main() {
  Set s1, s2(100);
  { Set s3(50); }                      // After "}", "s3" doesn't exist anymore
  std::cout << Set::NumberOfCreated(); // Should print 3
  std::cout << Set::NumberOfActive();  // Should print 2
  return 0;
}

I get two errors:

invalid use of member ‘Set::created’ in static member function

invalid use of member ‘Set::active’ in static member function

Also, this logic would always give the same output for active and created class instances. Could you give me a better approach to how to find number of active elements?

  • Note: main function cannot be changed! Only class should be changed to enable this functionality.

CodePudding user response:

You need created and active to be static data members, since they are supposed to describe global state of the program, not individual state of an instance of the class.

Then in every (non-delegating) constructor, including the copy/move constructor which are otherwise defined implicitly and will not count correctly, you will need to increment them. In the destructor you ought to decrement active since presumably if an object's lifetime ends you consider it non-active.

Also note that it is possible to end the lifetime of an object without calling its destructor by reusing its storage. Then the active counter would not account correctly. That is not something that should happen ordinarily though if the class is used properly.

If there are multiple threads you need to add a mutex as static member and lock it prior to any write or read to the two counters or make the counters std::atomic variables.

You will also need to add overflow checks and decide what to do when that happens, since overflowing an int will cause undefined behavior.

CodePudding user response:

you have multiple problems, here is how it can be done, check comments:

#include <iostream>
#include <stdexcept>

class Set {
  double value;
  static int created; // you need single variable for all instances, this is why static
  static int active;
public:
  Set();
  Set(double num);
  ~Set() {
      --active; // destructor is called when object is destroyed, so number of active instances is decreased
  }
  static int NumberOfCreated();
  static int NumberOfActive();
};

int Set::created = 0;
int Set::active = 0;

Set::Set() : Set(0) {} // this constructor should increase created/active counters as well, this can be achieved via calling another ctor
Set::Set(double num) : value(num) {
  created  ;
  active  ;
}
int Set::NumberOfCreated() { return created; }
int Set::NumberOfActive() { return active; }

int main() {
  Set s1, s2(100);
  { Set s3(50); }
  std::cout << Set::NumberOfCreated() << std::endl;
  std::cout << Set::NumberOfActive() << std::endl;
  return 0;
}

and of course follow @user17732522 comments about copy/move and thread safety

CodePudding user response:

The problem is that we can't use non-static data members created and active from inside static member function Numberof Created and NumberOfActive.

To solve this you can make created and active static and also make use of destructor to decrement active as shown below:

class Set {
      double value;
      //static data members 
      inline static int created = 0;
      inline static int active = 0;
  public:
      //static member functions 
      static int NumberOfCreated();
      static int NumberOfActive();
public:
  Set();
  Set(double num);
  //declaration for destructor 
  ~Set();
 
};

Set::Set() : value(0) {
      created;
      active;
    
}
Set::Set(double num) : value(num) {
  created  ;
  active  ;
}
//implementation for destructor
Set::~Set()
{
    //decrement active 
    --active;
}
int Set::NumberOfCreated() { return created; }
int Set::NumberOfActive() { return active; }
int main() {
  Set s1, s2(100);
  { Set s3(50); }                      
  std::cout << Set::NumberOfCreated()<<std::endl; // print 3
  std::cout << Set::NumberOfActive()<<std::endl;  //prints 2
  return 0;
}

The output of the above program is :

3
2

Working Demo

  • Related