通过指针映射访问类成员:Mgr能否获取Thing插入的Item实例?
问题:Mgr能否通过accessItem获取Thing插入的同一Item实例?
我有如下代码:
class Thing { private: Item item; }; class Mgr{ public: std::map<int, Item*> sps; }; void Thing::addItemToMap(std::map<int, Item*>& sps, int i){ sps.insert(std::make_pair(i, &(this->item))); } void Mgr::accessItem( int i){ auto it = sps.find(i); if(it!=sps.end()){ // it->second 是否为之前插入的Item实例? } }
请问当Thing调用addItemToMap方法以键i=3插入自身的item实例后,Mgr能否通过accessItem(3)获取到该Thing->item的同一实例?
当然可以获取到同一个实例!这里的核心逻辑很直接:
- 在
addItemToMap方法里,&(this->item)取的是当前Thing实例内部item成员的内存地址,插入到map里的就是这个地址对应的指针。 - 当Mgr调用
accessItem(3)找到这个指针后,it->second就是完全相同的指针——它指向的内存区域和Thing对象里的item是同一块,也就是说两者引用的是同一个Item实例。
不过这里有个必须重视的风险:一定要保证插入指针的Thing实例,在Mgr访问这个指针的整个期间都是存活的。如果Thing对象被销毁了,它内部的item成员也会被自动销毁,此时map里的指针就变成了「悬空指针」,访问it->second会触发未定义行为(比如程序崩溃、内存乱码等)。
举个典型的错误场景:
{ Thing tempThing; tempThing.addItemToMap(mgr.sps, 3); } // tempThing在这里被销毁,内部的item也随之释放 mgr.accessItem(3); // 此时访问it->second就是悬空指针,行为不可控
只要Thing实例的生命周期覆盖了Mgr访问指针的周期,你就可以安全地通过这个指针操作同一个Item实例。
内容的提问来源于stack exchange,提问作者ellysisland
相关产品推荐
相关产品推荐

