【发布时间】:2012-10-18 01:51:06
【问题描述】:
我希望标题不会太混乱。我拥有的是一个类StorageManager,其中包含从Storage 派生的类的对象列表。这是一个例子。
struct Storage {}; // abstract
class StorageManager
{
private:
map<string, unique_ptr<Storage>> List; // store all types of storage
public:
template <typename T>
void Add(string Name) // add new storage with name
{
List.insert(make_pair(Name, unique_ptr<Storage>(new T())));
}
Storage* Get(string Name) // get storage by name
{
return List[Name].get();
}
};
说Position是一种特殊的存储类型。
struct Position : public Storage
{
int X;
int Y;
};
感谢我的last question 上的出色答案,Add 功能已经有效。我要改进的是Get 功能。它合理地返回一个指针Storage* 我可以使用如下。
int main()
{
StorageManager Manager;
Manager.Add<Position>("pos"); // add a new storage of type position
auto Strge = Manager.Get("pos"); // get pointer to base class storage
auto Pstn = (Position*)Strge; // convert pointer to derived class position
Pstn->X = 5;
Pstn->Y = 42;
}
有没有办法通过自动返回一个指向派生类的指针来摆脱这种指针转换?也许使用模板?
【问题讨论】:
-
如果
Storage是基类,那么请给它一个虚拟析构函数。 -
感谢您的建议。我将在我的真实代码中使用它。
-
注意:使用
List[Name]的想法会造成尴尬。对于map和unordered_map,operator []将创建值(调用默认构造函数),如果它不存在的话。因此,如果您尝试使用不存在的名称来Get,则会创建指针,从而导致元素“泄漏”。 -
@MatthieuM。好在BigBoss给我提供了更好的解决方案。
标签: c++ class templates pointers return