获取活动 class 个实例的数量

Get number of active class instances

我需要获取创建的数量和活动的 class 个实例。

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

我收到两个错误:

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

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

此外,此逻辑将始终为活动和创建的 class 实例提供相同的输出。你能给我一个更好的方法来找到活动元素的数量吗?

您有多个问题,这是解决方法,查看评论:

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

当然还要关注@user17732522 关于copy/move 和线程安全

的评论

您需要 createdactive 成为 static 数据成员,因为它们应该描述程序的全局状态,而不是 class.

然后在每个 (non-delegating) 构造函数中,包括 copy/move 构造函数,否则它们将被隐式定义并且不会正确计数,您将需要递增它们。在析构函数中你应该减少 active 因为大概如果一个对象的生命周期结束你认为它 non-active.

另请注意,可以通过重用对象的存储来结束对象的生命周期而无需调用其析构函数。那么 active 计数器将无法正确计算。如果 class 使用得当,这不是通常应该发生的事情。

如果有多个线程,您需要添加一个互斥锁作为 static 成员,并在对两个计数器进行任何写入或读取之前将其锁定,或者使计数器成为 std::atomic 变量。

您还需要添加溢出检查并决定发生这种情况时要做什么,因为溢出 int 会导致未定义的行为。

问题是我们不能在static成员中使用non-static数据成员createdactive函数 Numberof CreatedNumberOfActive.

解决这个你可以使createdactive静态化,也可以使用析构函数来递减active,如下所示:

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

以上程序的输出为:

3
2

Working Demo