C++ C++;无序映射默认分配器

C++ C++;无序映射默认分配器,c++,class,inheritance,unordered-map,C++,Class,Inheritance,Unordered Map,我有一个抽象类(父类),刚从中创建了派生类(子类),如下所示: 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)

我有一个抽象类(父类),刚从中创建了派生类(子类),如下所示:

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...
    }
}
类父类{
公众:
虚拟字符串print()=0;
};
模板
类子:公共父类{
私人:
无序映射子对象;
公众:
父项*&运算符[](字符串名称){
返回子项[名称];
}
虚拟字符串打印(){
//一些工作。。。
}
}
嗯。现在我使用的派生类如下所示:

child<string> a;
a["test"]->print();
儿童a;
a[“测试”]->print();
问题就显现出来了

我认为问题在于无序映射::[]操作符创建了父类的实例,而不是我想要的子类的实例


假设您有一个
std::unordered_map
并执行以下操作,如何告诉unordered_map将新项目创建为

std::无序映射m;
std::cout
无序映射::操作符[]
不会创建任何类的实例,因为它的值是指针,而不是类实例。因此,如果您使用它访问之前未插入到映射中的密钥,它将默认初始化指针(将其初始化为nullptr)并将其存储在映射中

如果要在映射中使用任何非nullptr值,则需要自己将其存储在那里。您可以在
操作符[]
函数中执行此操作:

    parent *&operator[](string name) {
        if (children.find(name) == children.end()) // does it exist?
            children[name] = new child<T>; // if it doesn't, create a new one.
        return children[name];
    }
parent *&operator[](string name) {
    auto &rv = children[name];
    if (!rv) rv = new child<T>;
    return rv;
}
parent*&运算符[](字符串名称){
auto&rv=子项[名称];
如果(!rv)rv=新子女;
返回rv;
}
如果您覆盖通过引用返回的任何指针,并且需要在析构函数中释放它们,那么这就有泄漏内存的危险。您可以通过返回
parent*
而不是
parent*&
来避免前一个问题,或者在映射中使用
std::unique\u ptr
并在此处返回
std::unique\u ptr&
,然后调用
a[“test”]->print()
您应该在那里添加一个对象,
a[“test”]=新的子对象
或在
操作符[]
中添加
if(children.find(name)==children.end())children[name]=new child