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)
,则不会看到额外的破坏。@现在,所有内容都清楚了,谢谢。