std::map 成员都引用同一个地址

std::map Members refering all to one address

我正在使用 std::map,类似于 webrtc 中的实现(参见 here)。 我的地图是这样定义的:

typedef std::map <std::string, BaseOption*> OptionMap;

并且BaseOption(选项)定义为:

class BaseOption {
public:
    virtual ~BaseOption() {}
};

template<typename T>
class Option : public BaseOption {
public:
    explicit Option(T* v) {value = v;}
    ~Option() { delete value; }
    T* value;
};

集合成员:

template<typename T>
void ClassFoo::Set(OptionIdentifier option_, T* value) {

    BaseOption*& option_member = options_[option];
    delete option_member;
    option_member = new Option<T>(value);

}

我从一个叫做 class 的成员 put_into_map 调用填充地图(只是一个快速而肮脏的实现来测试我的 class):

void ClassFoo::put_into_map(){

    int tempval = 8000;

    this->Set<int>("IeAIf", &tempval);
    this->Set<int>("LcE8V", &tempval);

    tempval = 16000;
    this->Set<int>("RVn1C", &tempval);
    this->Set<int>("XINa2", &tempval);

    tempval = 1;
    this->Set<int>("st6Vz", &tempval);

    this->printAll<int>();
}

并从主要使用:

int main(){
    ClassFoo foo_object = new ClassFoo();
    foo_object->put_into_map();

    return 0;
}

printAll 的工作方式如下:

template<typename T>
void ConfTool::printAll(){

    std::cout << "#Elem in Map " << this->options_.size() << std::endl;

    OptionMap::const_iterator it;
    for (it = options_.begin(); it != options_.end(); ++it)
    {
        std::cout << "Arg: " << it->first <<    "  Value: \t" << static_cast<Option<T>*>(it->second)->value   << std::endl;
    }
}

在地图中插入不同的东西,并转储它(或使用它),所有选项都具有相同的值。同时转储这些值后面的地址,显示相同的空格(插入一些随机数据):

Arg: IeAIf  Value:  0x7fffc49980cc
Arg: LcE8V  Value:  0x7fffc49980cc
Arg: RVn1C  Value:  0x7fffc49980cc
Arg: XINa2  Value:  0x7fffc49980cc
Arg: st6Vz  Value:  0x7fffc49980cc

我假设我没有以正确的方式设计 Set-Member。

您需要重新考虑您的设计。由于在 Option::value.

中存储了相同的指针 (&tempval),因此在输出中得到相同的指针

如果你打印了it->second,你会发现这个特定的指针是不同的。但是当你得到 value,即 (it->second)->value,你最终会得到 &tempVal,就像你编码的那样。

换句话说,程序完全按照描述的方式运行——您存储了一个指针,您将获得该指针。您的设计中没有 "extracts" 位于指针处的值并将其放置在新的 Option 实例中。

这是您的代码的一个最小示例:http://ideone.com/jn5GtU

请注意,it->second 持有的地址正在改变,但 it->second->value 没有改变。它也恰好是&tempVal