首页 > 解决方案 > 如何准确检查类构造函数计数?

问题描述

我正在构建一个包含类创建计数的新类。我的代码中是否还有另一个异常,请检查创建计数?

我想知道剩余类A的计数。

因此,我创建了包含createCount在构造函数或析构函数调用时增加或减少的类 A。

class A { 
    public :
        static int createCount;
        int m;

        A(int m = 0) : m(m) {
            createCount++;
        }

        ~A() {
            createCount--;
        }
};
int A::createCount = 0;

我认为上面的代码没有问题,但是当我使用时vector,createCount 发生了意外的变化。

int main() {
    vector<A> aVector;
    aVector.push_back( A(1) ); // expected 1, real 0
    aVector.push_back( A(2) ); // expected 2, real -1
    aVector.push_back( A(3) ); // expected 3, real -3
}

我对上层代码的回答如下。

// for this answer, i search with "rules of ...(zero, five, ..)"
class A {
    /* same like upper */
    A(const A& other) {
        createCount++;
    }
};

但我不确定我的回答是否有另一个例外或一些问题。

我想知道上面的代码仍然有同样的问题。

感谢您阅读我的问题。

标签: c++class

解决方案


我想知道上面的代码仍然有同样的问题。

答案正如您所说:违反三/五规则。如果没有复制构造函数,std::vector::push_back将使用 POD 副本,它只是复制数据成员,A但不知道您正在寻找的引用计数副作用。

再深入一点:当你调用 时aVector.push_back(A(1)),首先A(1)构造一个A. 然后push_back将该值复制(或移动)到向量中,最后销毁临时值。

因为您既没有提供复制构造函数也没有提供移动构造函数,因此存在于向量中的新副本A不会增加您的计数。但是当临时A(1)对象被销毁时,计数仍然会减少。因此,每次推送操作都会导致计数减少。

我修复了您的复制构造函数,因为它是错误的:

A(const A& other) : A(other.m) {}

添加复制构造函数后,如果需要,您将需要指定移动构造函数。在这种情况下,这有点微不足道,因为不必移动实际数据,因此您可以A(int)再次使用构造函数。

A(A&& other) : A(other.m) {}

当然,一个移动实际上不应该增加或减少计数,但是你没有逻辑将它分开A

另请注意,您的代码不是线程安全的。如果需要,请使用 astd::atomic作为计数。


推荐阅读