我对以下代码中描述的类有以下问题:
#include <vector>
#include <tuple>
#include <map>
using namespace std;
class Widget
{
public:
Widget( int x, int y, int z ) : m_x{x}, m_y{y}, m_z{z} {}
private:
int m_x, m_y, m_z;
};
class Coord {
public:
Coord( int x, int y, int z ) : p{x}, q{y}, r{z} { }
std::tuple<int,int> get_tuple() { return std::make_tuple(p, q); }
int x() { return p; }
int y() { return q; }
int z() { return r; }
private:
int p, q, r;
};
class Collector
{
public:
Collector(const std::vector<Coord>& pool) { collect(pool); };
void collect(const std::vector<Coord>& pool)
{
for ( auto v : pool )
{
tuple<int,int> key = v.get_tuple();
auto value = make_shared<Widget>(v.x(), v.y(), v.z());
m_container.insert(make_pair(key, value));
}
}
private:
map< tuple<int,int>, shared_ptr<Widget> > m_container;
};
int foo()
{
Coord a{0,0,1};
Coord b{0,1,0};
Coord c{1,0,0};
vector<Coord> pool{a, b, c};
auto col = std::make_shared<Collector>( pool );
return 0;
}
我想知道它是否符合RAII标准。如果没有,我该如何修改它的实现来实现它。
我想确认地图Collector::m_container
存储在免费商店中。元组键和小部件都存储在免费商店吗?
foo
是否会泄漏内存?
分配的资源按什么顺序销毁?
答案 0 :(得分:4)
是的,您的每个对象都是RAII对象,这意味着当它被销毁时会释放所有获取的资源。
Widget
没有获得任何资源,因此没有任何资源可供免费使用。同样适用于Coord
。通常,只要模板参数是标准库模板就是RAII。因此std::shared_ptr<Widget>
是RAII对象,std::map< std::tuple<int, int>, std::shared_ptr<Widget>>
也是如此。
m_container
是结构数据成员。形式上,如果在堆栈上创建Collector
,则m_container
将在堆栈中,如果使用Collector
创建new
,则m_collection
将在免费商店。但是,std::map
的标准库定义通常可以通过创建&#34;映射节点&#34;使用new
,std::map
对象本身只能保存一些(固定)指向某些节点(根对象等)的指针。总的来说,它拥有的几乎所有内存都在免费商店中,正如你所说,但正式实体m_container
可以在内存中的任何地方。
foo
不会泄漏任何内存,构造的每个对象都是RAII对象,因此所有内存都会在销毁时释放。
您可以保证foo
中的五个不同的局部变量按照相反的构造顺序销毁。但是,在更详细的细节层面上,它是实现定义的,例如,std::map
节点被销毁的顺序。
答案 1 :(得分:-1)
RAII没有严格的合规标准。你的问题不清楚。
这是无法回答的,因为程序甚至无法编译。
有些工具可以为您检测内存泄漏(或至少某种类型),学会使用它们!此外,您可以简单地将调试输出添加到析构函数,并将它们与构造函数中的类似调试输出进行匹配。确保你抓住所有构造函数!
请参阅问题3的答案。