我正在尝试用 C++ 创建一个通用存储类。如果您查看下面的代码,我想存储 string
/AnyType
的映射并访问它们。
class StoresTestC
{
public:
template < class SettingsType >
std::map< std::string, SettingsType >* getStore(std::string const&);
private:
std::map< std::string, void* > stores_;
};
template < class SettingsType >
std::map< std::string, SettingsType >* StoresTestC::getStore(std::string const& name)
{
if (stores_.count(name) > 0)
{
void* temp = this->stores_[name];
return (std::map< std::string, SettingsType >*)(temp);
}
else
{
std::map< std::string, SettingsType > * result = new std::map< std::string, SettingsType > ();
this->stores_[name] = result;
return result;
}
}
我看到这样做有两个明显的危险:
如果我用错误的
SettingsType
/name
调用它,我将调用错误的转换,据我所知(我可能错了)会导致到未定义的行为。它会造成内存泄漏,但我有一个解决方案(这里公开了两个长)。
是否还有其他可能出错的地方,您能预见吗?
最佳答案
首先退后一步,确保您真的想要这样做。然后再看一遍您的设计。
好的,你还需要这个功能吗?
使用 std::map<std::string, boost::any>
boost::any
在哪里始终是 map
类型。然后当你使用 any_cast
或任何使项目退出的机制,您可以保证它是正确的类型或它会抛出,因此您永远不会冒未定义行为的风险。另外由于 any
从值(value)上看,您也没有可能的内存泄漏。
我还应该注意,在您的原始解决方案中,如果您使用 shared_ptr<void*>
它会记住如何删除存储在 shared_ptr
中的原始类型从而消除您提到的内存泄漏。
编辑:我看不出类似这样的任何其他明显的技术问题。但是请注意,拥有这样的 map 可能/可能会给 future 的维护者带来认知(“grokking”)问题,并且确实会在一定程度上增加代码的复杂性。
关于c++ - 从 void 指针转换(创建通用存储)有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13977579/