如何在程序中安全(并且轻松)计算类的所有*实例?

sje*_*397 6 c++

我希望能够实例化一个特定的(和其他正常的)类(我可以修改它的源)并计算类实例化的次数(例如像这样).但是我希望将所有实例包含在我的总计数中,甚至包括通过标准容器中的复制构造函数创建的实例.

让我的类的所有构造函数(包括复制构造函数)增加静态计数器是否合适?如果是这样,是否可以通过覆盖其他运算符来确保我的类仍然符合标准容器的要求(即T(x)等于x)?

Nic*_*pat 9

实现此目的的常用方法是使用您继承的类模板.

template <typename T>
class Countable
{
    static unsigned cs_count_;
public:
    Countable() { ++cs_count_; }
    Countable( Countable const& ) { ++cs_count_; }
    virtual ~Countable() { --cs_count_; }
    static unsigned count() { return cs_count_; }
};

template <typename T>
unsigned Countable<T>::cs_count_ = 0;
Run Code Online (Sandbox Code Playgroud)

所以要使用这个,我会写:

class MyClass : public Countable<MyClass> { };
Run Code Online (Sandbox Code Playgroud)

下面是一个线程安全的版本.它使用boost中的类来确保增量,减量和读取操作在支持的平台上是原子的.

#include <boost/detail/atomic_count.hpp>

template <typename T>
class Countable
{
    static boost::detail::atomic_count cs_count_;
protected:
    ~Countable() { --cs_count_; }
public:
    Countable() { ++cs_count_; }
    Countable( Countable const& ) { ++cs_count_; }
    static unsigned count() { return cs_count_; }
};

template <typename T>
boost::detail::atomic_count Countable<T>::cs_count_(0);
Run Code Online (Sandbox Code Playgroud)


Alb*_*ert 8

将静态类变量视为全局变量,它位于类的命名空间中.使用它增加或执行其他操作不会对其他代码产生任何副作用,即构造函数和其他运算符的行为与以前完全相同.

即,你是对的:只需增加所有构造函数并减少析构函数.


当然,正如George指出的那样,如果你想让多线程安全,你需要在访问你的计数器变量(例如一些互斥锁)时添加一些多线程安全代码.或者正如Steven指出的那样,您也可以使用原子递增/递减指令(但用法取决于平台).那些会快得多.但是,您必须要小心,因为在某些情况下,它不适用于多处理器环境.你可以使用Boost atomic_count来保证安全.