下面是一段代码,让我感到困惑:
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;
}
当我运行它时,这是输出:
Constructing Simple 1
Constructing Simple 2
Constructing Simple 3
Destructing Simple1
Destructing Simple1
Destructing Simple2
Destructing Simple1
Destructing Simple2
Destructing Simple3
Destructing Simple3
Destructing Simple2
Destructing Simple1
为什么在Simple1,Simple2,Simple3超出范围时,会多次调用析构函数?正如您所看到的,Simple1的析构函数甚至被调用4次,而simple3只被调用2次等。
你可以对此有所了解吗?
答案 0 :(得分:1)
因为向量存储了传递给它的每个对象的副本,所以这里创建的对象多于你看到的对象。
此外,矢量可以自由地创建其存储的对象的多个副本,根据标准对其没有限制。这通常发生在向量需要重新定位其内容时。
答案 1 :(得分:1)
构造函数的这三个调用
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);
执行然后向量重新分配内存。在内存的新范围内,它使用复制构造函数来复制第一个元素,同时删除前一个内存区域中的元素。
Destructing Simple1
当声明
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