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

C++ 识别复制构造函数的隐藏调用,c++,copy-constructor,C++,Copy Constructor,我在测试我的一些处理节点的代码,在构造函数和析构函数中放置一些打印输出,我意识到有3个隐藏调用要复制构造函数。但是,查看代码,我只能确定为什么会发生两个隐藏调用,而不能确定第三个 每个节点都有其标识级别和一些其他数据。我有一种单例类,从某种意义上说,它可以为每个不同的级别创建单例dummy。代码如下: class Node{ public: Node(...) { myNumber = Node::counter++; std::cout << "

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

每个
节点
都有其标识级别和一些其他数据。我有一种单例类,从某种意义上说,它可以为每个不同的级别创建单例
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;
}
我从我的输出中意识到,有3个隐藏的复制构造函数调用(因为如果
节点
的构造不同,它将有一个不同的
myNumber
,而且,所有“我的”构造函数都打印一个输出)

你能帮我解释一下为什么3个隐藏电话都在发生吗?我能猜出三分之二的原因是:

  • 调用
    std::make_pair
    时复制
    节点
  • 执行
    插入时复制该
    (以及随后的
    节点
    ,即
    第二个
  • ???我不知道第三个电话是什么

很抱歉,如果代码中有任何错误,这实际上是一个更大项目的一部分,我试着把一段最小的代码作为一个例子。如果发现任何错误,我将尝试更正。

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

这一切都取决于
std::map
的实现,我们对此一无所知。这可能是因为
std::map
所做的排序,也可能是完全不同的。编译器是什么?您是在C++03或C++11模式下编译的吗?@T.C.我仍然在使用C++03。
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