【问题标题】:Object counting copy constructor called more times than the destructor对象计数复制构造函数调用次数多于析构函数
【发布时间】:2018-08-14 20:51:12
【问题描述】:

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

问题是在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;
}

【问题讨论】:

  • 显示插入的代码怎么样?
  • 哦..是的,对不起。它在构造函数中。
  • 您帖子的标题没有说明问题是帖子。请问可以修吗?
  • 我没有看到任何“主要”功能

标签: c++ oop constructor destructor


【解决方案1】:

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

发生了什么:

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

【讨论】:

    【解决方案2】:

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

    如果您有一个重要的析构函数,您总是需要考虑如何正确定义复制构造函数和复制赋值运算符。阅读the rule of five

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 2015-12-05
      • 2017-02-08
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 2010-11-10
      相关资源
      最近更新 更多