首先,抱歉我的英文:
我设计了一个小库来管理我的程序使用的内存。主要是它实现了一种具有内存管理目的的共享对象。我有以下类(我省略了其他成员和函数,我不需要在这里解释我的问题):
packet
的参数化结构,包含T
类型的子对象和计数器:template<class T> struct packet { T t; unsigned counter; };
ptrstack
的参数类:一个带有析构函数的stack
,当调用析构函数时,它会为堆栈包含的每个指针调用delete
:template<typename T> struct ptrstack : public std::stack<T*> { ~ptrstack() { while(!this->empty()) { delete this->top(); this->pop(); } } };
pool
的类,带有静态参数函数(当然还有其他代码),返回对ptrstack
的引用:class pool { template<class T> using stack_tp = ptrstack<packet<T> >; public: template<class T> static stack_tp<T>& get() { static stack_tp<T> pool; return pool; } };
shared_obj
template<typename T> class shared_obj { /* Members (see below) */ };
shared_obj
:struct internals_t; // definition in a .cpp source code (pImpl idiom). // `shared_obj` uses only pointer to its type parameter. class user_t : public shared_obj<internals_t> { // member functions accessing its internal pointer. // `user_t` is very light. It only mantains a pointer, but it could be used as // a common object. // moreover, I can work with dynamic objects without using new and delete // since the memory is managed by shared_obj };
构造,分配/复制和销毁从根本上执行以下操作:
shared_obj<T>
时,都会在堆中创建packet<T>*
。shared_obj<T>
时,其关联数据包的计数器都会递增。shared_obj<T>
的析构函数时,其关联数据包的计数器都会递减。pool::get<T>().push(ptr);
packet<T>*
,并且其类型的池为空时,在堆中创建一个新的数据包。如果池不为空,我使用new的“就地”版本:new (pool::get<T>().top()) T(args); pool::get<T>().pop();
因此,在程序退出时委托销毁,并且所有创建的内存都可以重复使用。
足够的解释!!
我的问题是:我需要任何其他类型为“user_t
”的静态对象(实际上,不同类型的不同对象继承shared_obj
),但它们中的任何一个都会产生内存泄漏,我的原因如下:
packet_pool.get<T>()
的定义在定义之后被实例化:模板定义在第一个使用指针中实例化为具体类型,而不是模板的写入位置。因此,我的文件中的词法顺序与我翻译单元中的定义顺序不同。我的疑问终于如下:
这是一个平行的问题:
pools
吗?