C++ 在超出范围期间为类调用析构函数

C++ 在超出范围期间为类调用析构函数,c++,class,C++,Class,下面有一段代码,让我很困惑: class Simple { private: int m_nID; public: Simple(int nID) { std::cout << "Constructing Simple " << nID<< std::endl; m_nID = nID; } ~Simple() { std::cout << "

下面有一段代码,让我很困惑:

class Simple 
 {
   private:
    int m_nID;
   public:
     Simple(int nID)
     {
      std::cout << "Constructing Simple " << nID<< std::endl;
      m_nID = nID;
     }
    ~Simple()
     {
     std::cout << "Destructing Simple" << m_nID << std::endl;
     } 
    int GetID() { return m_nID; }
 };
typedef struct player 
 {
   char                         id;
   char                         nick[30];
   std::vector<Simple>          mVector;
 } player, *PPER_player;

 int main()
 {
   Simple Simple1(1); // allocating on stack
   Simple Simple2(2);
   Simple Simple3(3);

   player stackplayer; 
   stackplayer.mVector.push_back(Simple1);
   stackplayer.mVector.push_back(Simple2);
   stackplayer.mVector.push_back(Simple3);
  return 0;
} 
当Simple1、Simple2、Simple3超出范围时,为什么要多次调用析构函数?如您所见,Simple1的析构函数甚至被调用了4次,而simple3仅调用了2次,以此类推


你能解释一下吗?

因为向量存储了你传递给它的每个对象的副本,所以这里创建的对象比你看到的要多。

此外,向量可以自由创建其存储的对象的任意多个副本。根据标准,这方面没有限制。这通常发生在向量需要重新定位其内容时。

这三个构造函数调用

Constructing Simple 1
Constructing Simple 2
Constructing Simple 3
符合陈述

   Simple Simple1(1); // allocating on stack
   Simple Simple2(2);
   Simple Simple3(3);
那么当声明

   stackplayer.mVector.push_back(Simple1);
执行隐式定义的复制构造函数

这句话是什么时候说的

   stackplayer.mVector.push_back(Simple2);
   stackplayer.mVector.push_back(Simple3);
然后执行向量重新分配内存。在内存的新区段中,它使用复制构造函数复制第一个元素,同时删除前一个内存区段中的元素

 Destructing Simple1
声明什么时候发表

   stackplayer.mVector.push_back(Simple2);
   stackplayer.mVector.push_back(Simple3);
向量再次分配一个新的内存范围,并复制其中的两个元素。所以这些对析构函数的调用

 Destructing Simple1
 Destructing Simple2
与此操作相对应

退出主要对象stackplayer范围后;已删除。析构函数的这些调用对应于此操作

 Destructing Simple1
 Destructing Simple2
 Destructing Simple3
最后,本地对象Simple1、Simple2和Simple3按与其创建顺序相反的顺序删除

 Destructing Simple3
 Destructing Simple2
 Destructing Simple1

向量需要将其元素存储在连续的存储区域中。如果推送的元素多于向量当前分配的存储区域的容量,则向量需要1)分配更大的元素2)将所有元素从旧存储移动到新存储,并将新元素推送到新存储,3)删除旧存储。第三点是你所观察到的破坏的原因。如果在执行
推回
s之前调用向量上的
reserve(6)
,则不会看到额外的破坏。@现在,所有内容都清楚了,谢谢。