对象计数复制构造函数的调用次数比析构函数多

Object counting copy constructor called more times than the destructor

本文关键字:析构函数 调用 复制 构造函数 对象      更新时间:2023-10-16

我在这个类事务中有一个多映射,我在其中存储日期事务(我有另一个日期类(。当对象被实例化时,它将自动添加到多映射中。

问题是在 main 函数中,在我实例化一个对象后,事务数是 2 而不是 1。

由于多映射插入,复制构造函数被调用 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;
}
如果要

跟踪类的所有对象,则必须检测其所有构造函数,包括复制(和移动(构造函数。

正在发生的事情是:

  1. Transaction对象是使用您提供的构造函数创建的。
  2. datedTransactions.insert(std::make_pair(date, *this));使用类的复制构造函数创建一个临时Transaction对象(在对内(。
  3. 映射中的新 Transaction 对象由临时移动构造函数初始化。
  4. 临时被销毁,这是您看到触发的析构函数。

您似乎没有复制构造函数,因此通过复制创建的任何临时Transaction对象都不会插入到映射中,但在销毁它们时仍会减少计数器。

如果你有一个重要的析构函数,你总是需要考虑如何正确定义复制构造函数和复制赋值运算符。阅读有关五法则的信息。

要解决您的问题,您可以向类添加一个 bool 标志,该标志仅对插入到映射中的对象设置为 true,对于任何副本设置为 false。然后在析构函数中,仅当标志为 true 时才减少计数器。