STL之queue使用
std::queue是一种先进先出的数据结构,它并不是一个真正的容器,而是一处适配器,它是对std::deque的包装。其定义如:模板的第二个参数指定了queue的实现是std::deque。1,std::queue的push操作如果std::queue保存的对象,则push操作时,会调用对象的拷贝构造函数,插入queue中的是对象的一份拷贝。#include <queue>#incl
std::queue是一种先进先出的数据结构,它并不是一个真正的容器,而是一个适配器,它是对std::deque的包装。其定义如:
模板的第二个参数指定了queue的实现是std::deque。
1,std::queue的push操作
如果std::queue保存的对象,则push操作时,会调用对象的拷贝构造函数,插入queue中的是对象的一份拷贝。
#include <queue>
#include <iostream>
#include <string.h>
class Test
{
public:
Test(int value): mValue(value)
{
}
Test(const Test& another)
{
mValue = another.mValue;
std::cout << "copy construtor" << std::endl;
}
~Test()
{
std::cout << "destructor" << std::endl;
}
void print()
{
std::cout << mValue << std::endl;
}
private:
int mValue;
};
int main()
{
std::queue<Test> qTest;
Test test1(10);
qTest.push(test1);
Test data = qTest.front();
data.print();
return 0;
}
从执行结果看出,在调用push的时候调用了对象的拷贝构造函数,在调用front时也调用的对象的构造函数,一共是生成了3个对象,所以最后有3个析构函数调用。如果是push对象的指针会是什么样的呢?修改main函数如下
int main()
{
std::queue<Test*> qTest;
Test *test1 = new Test(10);
qTest.push(test1);
Test *data = qTest.front();
data->print();
delete test1;
return 0;
}
2,std::queue 的front和pop操作
queue的front操作其实只要记住queue里保存的是什么类型,front返回的就是什么类型。从上面的例子可以看出,而pop操作是从queue里删除元素,它其实是只是调用了元素对象的析构函数,如
c 的类型
调用析构函数
而_M_impl的类型为
但看结构体_Deque_impl里并没有destroy函数,那应该是在基类_Tp_alloc_type里,所以去看_Tp_alloc_type的定义
从这里可以看到_Tp_alloc_type实际是一个typedef,其实际类型为是_Alloc::template rebind<>模板类型,而_Alloc是模板形参
其实参
这里看到_Tp_alloc_type就是模板rebind里的other,但到这里还是看不到destroy函数,那还得往基类里找
最后到
修改 main函数如下
int main()
{
std::queue<Test> qTest;
Test test1(10);
qTest.push(test1);
Test data = qTest.front();
std::cout << "before pop!\n";
qTest.pop();
std::cout << "finish pop!\n";
data.print();
return 0;
}
用gdb跟出来的结果,pop时queue元素减少1,调用了对象的析构函数,然后我们还正常使用先前front返回的元素,其并没有真正被释放,而是待stl容器对象销毁时,其容器里的元素才被真正释放,而若是stl容器里存放的是new出来的对象则是需要手动释放的。修改main函数如下:
int main()
{
std::queue<Test*> qTest;
Test *test1 = new Test(10);
qTest.push(test1);
Test *data = qTest.front();
std::cout << "before pop!\n";
qTest.pop();
std::cout << "finish pop!\n";
data->print();
delete data;
return 0;
}
pop弹出的是指针类型,所以并没有看到调用Test的析构函数。而这个new出来的Test是需要我们手动去释放的,否则就是内存泄漏了。
更多推荐
所有评论(0)