std::map 成员引用所有地址

std::map Members refering all to one address

本文关键字:地址 成员 map std 引用      更新时间:2023-10-16

我正在使用std::map,类似于webrtc中的implemtentation(见这里)。我的地图定义如下:

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

并且定义了基本选项(选项):

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);
}

我从一个名为 put_into_map 的类成员调用填充映射(只是一个快速而脏的实现来测试我的类):

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;
}

打印所有工作如下:

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,完全按照你编码的方式。

换句话说,程序完全按照描述做——你存储了一个指针,你将得到指针。 设计中的任何内容都不会"提取"位于指针上的值并将其放置在新的 Option 实例中。

下面是显示这一点的代码的最小示例: http://ideone.com/jn5GtU

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