识别对复制构造函数的隐藏调用

Identifying hidden calls to copy constructor

本文关键字:隐藏 调用 构造函数 复制 识别      更新时间:2023-10-16

我正在通过在构造函数和析构函数中放置一些打印输出来测试我的一些处理节点的代码,我意识到有 3 个隐藏的调用来复制构造函数。但是,查看代码,我只能确定为什么会发生 2 个隐藏调用,而不是第三个

每个Node都有其识别级别和其他一些数据。我有一个 Singleton 类,从某种意义上说,可以为每个不同的级别创建单例dummy,然后使用对单例的引用。代码如下:

class Node{
   public:
   Node(...) {
      myNumber = Node::counter++;
      std::cout << "constructing Node: " << myNumber << std::endl;
      ... 
   } // normal constructor
   ~Node() { 
      std::cout << "deleting Node: " << myNumber << std::endl;
   }
   static Node &dummy(int level);
   private:
   static int counter;
   int myNumber;
   bool isDummy;
   static std::map<int, Node> dummies;     
   Node(int level) { 
      myNumber = Node::counter++;
      std::cout << "constructing dNode: " << myNumber << std::endl;
      ..
   } // private constructor, just for dummies
};
int Node::counter = 0;    
Node& Node::dummy(int level){
   std::map<int, Node>::iterator it;
   if ((it=Node::dummies.find(level)) == Node::dummies.end()){
      // no previous dummy present at this level
      it = Node::dummies.insert(std::make_pair(level, Node(level))).first;
      // this line invokes 3 HIDDEN CALLS TO COPY CONSTRUCTOR
   }
   return it->second;
}

然后,在我的(用户(代码中的某个时刻,我调用:

Node &myDummy5 = Node::dummy(5);
std::cout << "have dummy!" << std::endl;

当这是唯一的用户代码时,我得到的输出是:

constructing dNode: 0
deleting Node: 0
deleting Node: 0
deleting Node: 0
have dummy!
deleting Node: 0

我从我的输出中意识到发生了 3 个隐藏的复制构造函数调用(因为如果Node构造不同,它将具有不同的myNumber,而且,所有"我的"构造函数都打印输出(。

你能帮我为什么所有 3 个隐藏的电话都在发生吗?我可以猜测 2/3 的原因是:

  • 调用std::make_pair时复制Node
  • 执行insert时复制该pair(以及随后second Node
  • ???我不知道第三个电话可能是什么

抱歉,如果代码中有任何错误,这实际上是一个更大项目的一部分,我试图只放一段最小的代码作为示例。如果发现,我会尝试纠正任何。

所有 STL 容器都使用复制语义来管理其对象。 这就是为什么在将类与 STL 容器一起使用之前,您的类支持复制构造和复制赋值是一个先决条件。 因此,在引擎盖下,std::map正在使用副本来组织您的对象。 这就是我们所知道的,它取决于它将为给定任务复制对象的次数