代码之家  ›  专栏  ›  技术社区  ›  sje397

我如何安全地(并且容易地)计算程序中某个类的*所有*实例?

c++
  •  6
  • sje397  · 技术社区  · 14 年前

    我希望能够实例化一个特定的(或者其他普通的)类(我可以修改它的源),并计算类被实例化的次数(例如。 like this )但我希望在总计数中包括所有实例,甚至一些实例是通过标准容器中的复制构造函数创建的。

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

    2 回复  |  直到 14 年前
        1
  •  8
  •   Albert    14 年前

    将静态类变量视为仅在类的命名空间中的全局变量。用它递增或做其他事情不会对其他代码产生任何副作用,也就是说,您的构造函数和其他运算符的行为将与以前完全一样。

    也就是说,您是对的:只需增加所有构造函数,减少析构函数。


    当然,正如乔治指出的那样,如果你想让它多线程安全,你需要在访问你的计数器变量(例如一些互斥体)的过程中添加一些多线程安全代码。或者如Steven所指出的,您也可以使用原子增量/减量指令(但使用情况将取决于平台)。那会快很多。但是,您必须小心,因为在某些情况下,在多处理器环境中无法工作。你可以使用Boost atomic_count 为了安全起见。

        2
  •  9
  •   Nick Strupat    14 年前

    实现这一点的一种常见方法是使用从中继承的类模板。

    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;
    

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

    class MyClass : public Countable<MyClass> { };
    

    下面是线程安全版本。它使用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);