【问题标题】:Class that automatically keeps track of the number of its instances in existence (C++)自动跟踪现有实例数的类 (C++)
【发布时间】:2022-11-16 09:05:25
【问题描述】:

我的任务是创建一个 C 类,它会自动跟踪其存在的实例数,并提供一个返回该数字的函数。

这是我所拥有的:

class C{
   public:
       static int num;

       C(){++num;}
       ~C(){--num;}

       int get_number_objs(){return num;}
};

int C::num = 0;

这能解决问题吗?

这看起来很简单并且可能有道理,但我想知道是否存在边缘情况,您会乱用指针或类似的东西,让某些东西从裂缝中掉下来。

这是解决方案的验证,比什么都重要。

【问题讨论】:

  • C c; C d = c; std::cout << d.get_number_objs(); 测试它。或者换个角度看:你显然违反了rule-of-three,所以可能有问题。
  • 所以我还需要重载复制构造函数和复制赋值构造函数,对吗?
  • 以及在必要时移动构造函数和移动赋值运算符。虽然我相信在大多数情况下您可以默认赋值运算符。他们不会增加或减少计数。
  • @RedRubber 只有复制构造函数(和移动构造函数)。赋值运算符只是将成员数据从现有实例复制/移动到另一个现有实例,它不会创建新实例,只有构造函数会这样做。

标签: c++ class object static


【解决方案1】:

这能解决问题吗?

几乎。您还需要在类的复制构造函数以及 C++11 及更高版本中的移动构造函数中递增 num

此外,如果 numpublic,那么使用 get_number_objs() 也没有意义,但由于这确实将 num 暴露给外部篡改,因此 num 应该改为 private。而get_number_objs()应该是static

尝试这个:

class C{

   private:
       static unsigned num;

   public:
       C(){ ++num; }
       C(const C&){ ++num; }
       C(C&&){ ++num; }

       ~C(){ --num; }

       static unsigned get_number_objs(){ return num; }
};

unsigned C::num = 0;

或者,在 C++17 及更高版本中,您可以 inline num 变量,这样您就不必在类之外单独定义它:

class C{

   private:
       static inline unsigned num = 0;

   public:
       C(){ ++num; }
       C(const C&){ ++num; }
       C(C&&){ ++num; }

       ~C(){ --num; }

       static unsigned get_number_objs(){ return num; }
};

【讨论】:

  • 这是有道理的。不过我想澄清一件事——既然我们已经声明了一个移动构造函数,我们也有义务重载复制赋值,是吗? (无论如何,对于复制赋值不应该增加num)。如果我在这方面是正确的,如果我们完全跳过重载移动分配会发生什么?什么情况下会出现故障?我能想到的例子是移动构造函数发挥作用,从对象移动无论如何都是临时的。
  • 我们也有义务重载复制分配,是吗?“ - 不,因为您的类没有任何需要复制/移动的非静态数据成员,所以编译器生成的默认运算符就足够了。无论如何,您确实需要了解两者之间的区别建造任务, 他们是两个不同的东西。
  • 我认为在 C++11 及更高版本中,user defined move constructor disables the implicit copy constructor。我的意思是,我只是确定自己定义它不是问题。
  • 显示的类没有隐式生成的复制构造函数,它有一个用户定义的复制构造函数:C(const C&)
猜你喜欢
  • 1970-01-01
  • 2021-12-24
  • 2023-01-03
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
相关资源
最近更新 更多