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
。
我正在使用 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
。