我正在构建一个包含CLASS创建计数的新CLASS。我的代码中还有其他异常,请检查创建计数吗?
我想知道保持类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++;
}
};
但是我不确定我的答案是否还有另一个例外或问题。
我想知道上层代码还是有同样的问题。
感谢您阅读我的问题。
答案 0 :(得分:1)
我想知道上层代码还是有同样的问题。
答案正好是您所说的:违反三五规则。如果没有副本构造函数,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) {}
添加复制构造函数后,如果需要,则需要指定move构造函数。在这种情况下,由于不需要移动任何实际数据,因此有点琐碎,因此您可以再次使用A(int)
构造函数。
A(A&& other) : A(other.m) {}
当然,移动实际上不应该增加或减少计数,但是您没有逻辑在A
中将其分开。
还请注意,您的代码不是线程安全的。如果需要,请使用std::atomic
作为计数。