C ++ unordered_map默认分配器

问题描述 投票:0回答:1

我有一个抽象类(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

c++ class inheritance unordered-map
1个回答
0
投票

假设您有一个std::unordered_map<std::string, int>,并且执行以下操作:

std::unordered_map<std::string, int> m;
std::cout << m["hello"];
std::cout << m["key1"];

以上程序不会产生任何警告或错误。实际上,它将输出00。两个零。那么,这里发生了什么?

unordered_mapmapoperator[]插入一个值,如果键不存在。这是C ++中意外错误的最大来源之一。在上述情况下,"hello""key1"不存在,因此它们是使用value默认值初始化为0的原位创建的。

如何解决您的问题?

总是在使用operator[]之前确保您尝试访问的值是否存在。实际上,如果要执行读取,最好使用.at()成员函数。

固定代码:

child<string> a;
a["test"] = new child<string>;
a["test"]->print();

您可以通过更改operator[]功能来进一步防止此行为:

    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];
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.