C++查找实例化的模板
C++ finding the instantiated templates
我刚刚在代码中发现了以下宝石(示例非常简化,但逻辑相同):
template <class T>
class garbage_bin
{
private:
garbage_bin<T>(void)
{
}
static garbage_bin<T>* pinstance;
public:
static garbage_bin<T>& instance()
{
if(pinstance == NULL)
{
pinstance = new garbage_bin<T>();
}
return *pinstance;
}
void empty()
{
for(size_t i=0; i<items.size(); i++)
{
free (items[i]);
}
}
void throwIn(T item)
{
items.push_back(item);
}
vector<T> items;
};
然后在代码中的某个地方(这只是一个例子......像这样的有数千个):
char* r = strdup(src);
garbage_bin<char*>::instance().throwIn(r);
后来在代码中的某个地方,就在退出之前......
garbage_bin<char*>::instance().empty();
garbage_bin<molecules*>::instance().empty();
garbage_bin<CDatabaseUsers*>::instance().empty();
等等...
因此,正如我们所看到的,这实现了一个垃圾箱类,您可以在其中"扔入"所有类型的对象,并且在稍后阶段为了避免内存泄漏,您可以"清空"垃圾箱。但这里出现了一个大瓶颈:为了使它正常工作,你需要知道实例化了这个垃圾箱的所有类,以便清空它们......
我想到的最直接的解决方案是为实例化创建一个typeid
调用的映射,并将garbage_bin<T>::instance()
分配给名称,但是古代编译器决定他不喜欢这种方法。
显然,我可以搜索代码以找到所有模板化,但我想知道......有没有更简单的方法可以做到这一点?
垃圾
桶!
class garbage_bin_base;
class garbage_bin_bin {
public:
void throwIn(garbage_bin_base* rubbish) { items.push_back(rubbish); }
void empty() { for (auto item: items) item->empty(); }
private:
vector<garbage_bin_base*> items;
};
class garbage_bin_base {
public:
virtual empty() = 0;
garbage_bin_base() { garbage_bin_bin::instance().throwIn(this); }
};
template <typename T>
class garbage_bin : public garbage_bin_base {
};
您可以为要删除的内容添加注册表:
Registry registry;
// ...
if (pinstance == NULL)
{
pinstance = new garbage_bin<T>();
registry.add<T>();
}
// ...
registry.clear_all();
例如:
class Registry
{
struct Base
{
virtual ~Base() {}
virtual void clear() = 0;
};
template <typename T> struct Derived : Base
{
virtual void clear() { garbage_bin<T*>::instance().empty(); }
};
std::vector<std::unique_ptr<Base>> targets;
public:
void clear_all() { for (auto & p : targets) { p->clear(); } }
template <typename T> void add()
{
targets.emplace_back(new Derived<T>);
}
};
我宁愿用std::vector<std::unique_ptr<T>>
(或者,也许是std::vector<std::shared_ptr<T>>
)替换garbage_bin<T>
。
如果要限制接口,请将garbage_bin<T>
重新实现为std::vector<std::unique_ptr<T>>
的包装器。这样,您可能不需要 empty
方法,因为 std::vector
和 std::unique_ptr
的析构函数会在自己之后进行清理。但是,如果要在销毁之前清空垃圾箱,则只需调用std::vector::clear
即可实现empty
。
我知道这不是最简单的事情(因为 OP 说有"数千个"地方需要更改),但显然需要重构这个糟糕的设计。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 从模板实例化/类型推断中查找错误消息的实际来源
- 如何在源代码C++查找类的实例化
- C++查找实例化的模板
- 在模板实例化中查找从属名称C++
- 'make_error_code' 未在此范围内声明,并且在实例化点通过依赖于参数的查找未找到任何声明
- 在c++代码中查找未实例化的模板