对象计数复制构造函数调用次数多于析构函数
Object counting copy constructor called more times than the destructor
我在这个 class 事务中有一个多图,我在其中存储有日期的事务(我有另一个日期 class)。当对象被实例化时,它会自动添加到 multimap 中。
问题是在main函数中,我实例化一个对象后,事务数是2而不是1。
因为multimap插入,拷贝构造函数被调用了2次,而析构函数只被调用了一次。
除了再次减少构造函数中的交易数量外,我该如何解决?
class Transaction {
private:
std::string note;
float value;
Date date;
static unsigned int numberOfTransactions;
static std::multimap<Date, Transaction, Date::Comparator> datedTransactions;
public:
Transaction( Date date, std::string note, float value )
{
std::cout<<"Constructor is called";
this->date = date;
this->note = note;
this->value = value;
datedTransactions.insert(std::make_pair(date, *this));
}
~Transaction() {
std::cout<<"Destructor is called";
numberOfTransactions--;
}
Transaction( Transaction const & t ) {
std::cout<<std::endl<<"Copy constructor is called";
note = t.note;
value = t.value;
numberOfTransactions++;
}
Transaction& operator=(Transaction const &t) {
if (this != &t) {
note = t.note;
value = t.value;
}
}
static unsigned int GetNumberOfTransactions() {
return numberOfTransactions;
}
};
int main() { // main should return int & not void
Date date;
Transaction (date, "dinner", 100);
std::cout << std::endl << Transaction::GetNumberOfTransactions() << std::endl;
}
您似乎没有复制构造函数,因此通过复制创建的任何临时 Transaction
对象都不会插入到地图中,但在销毁它们时仍会减少计数器。
如果您有 non-trivial 析构函数,您 总是 需要考虑如何正确定义复制构造函数和 copy-assignment 运算符。了解 the rule of five。
要解决您的问题,您可以向 class 添加一个 bool
标志,该标志仅对插入地图的对象设置为 true,对任何副本都设置为 false。然后在析构函数中,如果标志为真,则只减少计数器。
如果您想跟踪 class 的所有对象,您必须检测 所有 其构造函数,包括复制(和移动)构造函数。
发生的事情是:
- 使用您提供的构造函数创建了一个
Transaction
对象。
datedTransactions.insert(std::make_pair(date, *this));
使用 class. 的复制构造函数创建临时 Transaction
对象(在对象对内)
- 映射中的新
Transaction
对象由临时对象的移动构造函数初始化。
- temporary被销毁了,也就是你看到触发的析构函数
我在这个 class 事务中有一个多图,我在其中存储有日期的事务(我有另一个日期 class)。当对象被实例化时,它会自动添加到 multimap 中。
问题是在main函数中,我实例化一个对象后,事务数是2而不是1。
因为multimap插入,拷贝构造函数被调用了2次,而析构函数只被调用了一次。
除了再次减少构造函数中的交易数量外,我该如何解决?
class Transaction {
private:
std::string note;
float value;
Date date;
static unsigned int numberOfTransactions;
static std::multimap<Date, Transaction, Date::Comparator> datedTransactions;
public:
Transaction( Date date, std::string note, float value )
{
std::cout<<"Constructor is called";
this->date = date;
this->note = note;
this->value = value;
datedTransactions.insert(std::make_pair(date, *this));
}
~Transaction() {
std::cout<<"Destructor is called";
numberOfTransactions--;
}
Transaction( Transaction const & t ) {
std::cout<<std::endl<<"Copy constructor is called";
note = t.note;
value = t.value;
numberOfTransactions++;
}
Transaction& operator=(Transaction const &t) {
if (this != &t) {
note = t.note;
value = t.value;
}
}
static unsigned int GetNumberOfTransactions() {
return numberOfTransactions;
}
};
int main() { // main should return int & not void
Date date;
Transaction (date, "dinner", 100);
std::cout << std::endl << Transaction::GetNumberOfTransactions() << std::endl;
}
您似乎没有复制构造函数,因此通过复制创建的任何临时 Transaction
对象都不会插入到地图中,但在销毁它们时仍会减少计数器。
如果您有 non-trivial 析构函数,您 总是 需要考虑如何正确定义复制构造函数和 copy-assignment 运算符。了解 the rule of five。
要解决您的问题,您可以向 class 添加一个 bool
标志,该标志仅对插入地图的对象设置为 true,对任何副本都设置为 false。然后在析构函数中,如果标志为真,则只减少计数器。
如果您想跟踪 class 的所有对象,您必须检测 所有 其构造函数,包括复制(和移动)构造函数。
发生的事情是:
- 使用您提供的构造函数创建了一个
Transaction
对象。 datedTransactions.insert(std::make_pair(date, *this));
使用 class. 的复制构造函数创建临时 - 映射中的新
Transaction
对象由临时对象的移动构造函数初始化。 - temporary被销毁了,也就是你看到触发的析构函数
Transaction
对象(在对象对内)