我有一个抽象类(parent),并且刚刚从中创建了派生类(child),如下所示:
class parent {
public:
virtual string print()=0;
};
template<class T>
class child: public parent{
private:
unordered_map<string, parent*> children;
public:
parent *&operator[](string name) {
return children[name];
}
virtual string print(){
//some jobs...
}
}
好的。现在我使用如下的派生类:
child<string> a;
a["test"]->print();
问题就出来了。
我认为问题在于 unordered_map::[] 运算符创建了一个 parent 类的实例,而不是我想要的 child 类。
如何告诉 unordered_map 创建新项目作为 child < string >
最佳答案
unordered_map<std::string, parent *>::operator[]
不会创建任何类的实例,因为它的值是指针,而不是类实例。因此,如果您使用它来访问之前未插入到映射中的键,它将默认初始化一个指针(将其初始化为 nullptr)并将其存储在映射中。
如果您想在映射中使用任何非 nullptr 值,您需要自己将它们存储在那里。您可以在 operator[]
中执行此操作功能:
parent *&operator[](string name) {
auto &rv = children[name];
if (!rv) rv = new child<T>;
return rv;
}
如果您覆盖任何通过引用返回的指针,则存在内存泄漏的危险,而且您需要在析构函数中释放它们。您可以通过返回 parent *
来避免前一个问题。而不是parent *&
,或使用 std::unique_ptr<parent>
在 map 中并返回 std::unique_ptr<parent> &
在这里。
关于C++ unordered_map 默认分配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62393504/