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

时间:2014-09-12 12:54:29

标签: c++ copy-constructor

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

每个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原因是:

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

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

1 个答案:

答案 0 :(得分:0)

所有STL容器都使用复制语义来管理其对象。这就是为什么在您将类与STL容器一起使用之前,您的类支持复制构造和复制分配的前提条件。因此,std::map正在使用副本来组织您的对象。这就是我们所知道的,它的实现依赖多少次它会复制你的对象以进行给定任务。