我是C ++的新手,所以仍然在学习指针并习惯使用它们。
我已经声明了一个对象映射,以便存储用户稍后可以使用标记键访问的对象。
map<string,MyObject*> myMap;
我添加到myMap的对象是在我的主要
调用的函数中创建的void myFunction(){
...
MyObject obj1();
MyObject* objPtr;
objPtr = &obj1;
myMap.insert(pair<string,MyObject*>("xxxx", objPtr));
...
}
当我执行这个函数时,对象指针完美地插入到myMap中,但是在函数执行后我失去了对obj1的引用我猜是因为指针和对象是在函数内部本地创建的,所以我仍然有一个元素“ xxx“在地图中,但我认为之后的空引用。
如何全局保留对象和引用?我想在函数中创建这个对象,因为它有一些需要从用户obj1(m,n)获取的变量参数。谢谢你的帮助。
答案 0 :(得分:4)
代码行
MyObject obj1;
定义了一个 local 变量,该变量包含MyObject
的实例。一旦将要保留此变量的上下文,该对象将被销毁。对对象的破坏并不意味着指向它们的指针将以任何方式被通知(例如它们未被设置为0),访问它们是无效的。
您基本上有以下选项:
在堆上而不是在本地创建对象。这是使用new
关键字完成的。但是在某些时候你必须delete
对象。
MyObject *obj1 = new MyObject(arguments...);
由于这通常很难管理,所以发明了智能指针。例如,自C ++ 11以来,添加了shared_ptr
(但在某些编译器中也可以使用预发布版本C ++ 0x)。当最后一个引用被销毁时,这种类型的智能指针会自动删除对象。
map<string,std::shared_ptr<MyObject>> myMap; // Note that I changed the type
std::shared_ptr<MyObject> obj1 = std::make_shared<MyObject>(arguments...);
myMap.insert(std::make_pair("xxxx", obj1));
顺便说一下,我使用了std::make_pair
,它会自动deduce the template types for you。
将值存储在地图中。根本不要使用指针。如果您的类型可以复制(某些类型不能)以及您的某些设计决策不禁止您这样做,则可以选择此选项。但在大多数情况下,将值存储在地图中是个好主意。从地图中提取要修改的元素时,请使用引用:
MyObject &obj = myMap["xxxx"]; // looking up the key
obj.doSomeAction(); // modify it; no need to re-insert
引用的行为类似于指针(即它们仅“指向”某个实例),但存在一些差异。例如,引用始终指向其生命周期内的同一实例(您无法重新分配引用)。此外,它们的语法等于值,即不需要->
。
就个人而言,如果您不需要在程序的多个位置指向同一个对象,我更喜欢第三个选项。如果是这种情况,我们会谈到“共享”对象,这正是您想要使用“共享”指针的情况。第一种选择是非常低级的,应该被认为是“过时的”。
答案 1 :(得分:2)
除非你有充分的理由不这样做,否则在地图中存储对象可能更简单:
map<string, MyObject> myMap;
然后:
void myFunction(){
...
myMap.insert(std::make_pair("xxxx", MyObject()));
...
}
答案 2 :(得分:1)
您可以动态实例化对象。
MyObject* objPtr = new MyObject;
但是当你不再使用
时不要忘记删除这个实例delete objPtr;