保留对象和对函数内创建的对象的引用

JLA*_*JLA 3 c++

我是 C++ 新手,所以仍在学习指针并习惯使用它们。

我声明了一个对象映射,以便存储用户稍后可以使用标签键访问的对象。

map<string,MyObject*> myMap;
Run Code Online (Sandbox Code Playgroud)

我添加到 myMap 的对象是在我的 main 调用的函数中创建的

void myFunction(){
    ...
    MyObject obj1();
    MyObject* objPtr;
    objPtr = &obj1;
    myMap.insert(pair<string,MyObject*>("xxxx", objPtr));
    ...
    } 
Run Code Online (Sandbox Code Playgroud)

当我执行这个函数时,对象指针完美地插入到 myMap 中,但是在函数执行之后,我丢失了对 obj1 的引用,我猜是因为指针和对象是在函数内部本地创建的,所以我仍然有一个元素“xxx”地图,但我认为后面是一个空参考。

如何全局保存对象和引用?我想在函数中创建这个对象,因为它有一些需要从用户 obj1(m,n) 获取的变量参数。谢谢你的帮助。

lee*_*mes 5

代码行

MyObject obj1;
Run Code Online (Sandbox Code Playgroud)

定义一个保存 的实例的局部MyObject变量。一旦该变量的上下文即将离开,该对象就会被破坏。对象的销毁并不意味着指向它们的指针将以任何方式得到通知(例如它们没有设置为0),访问它们是无效的。

您基本上有以下选择:

  • 在堆上而不是在本地创建对象。这是使用new关键字完成的。但到了delete某个时候你就必须接触到这个对象。

    MyObject *obj1 = new MyObject(arguments...);
    
    Run Code Online (Sandbox Code Playgroud)
  • 由于这通常难以管理,因此发明了智能指针。例如,从 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));
    
    Run Code Online (Sandbox Code Playgroud)

    顺便说一句,我使用了std::make_pair它会自动为你推导出模板类型

  • 将值存储在地图中。根本不要使用指针。如果您的类型可以复制(某些类型不能)并且您的某些设计决策不禁止您这样做,那么这是一个选项。但在大多数情况下,将值存储在地图中是个好主意。从地图中获取要修改的元素时,请使用引用:

    MyObject &obj = myMap["xxxx"]; // looking up the key
    obj.doSomeAction();            // modify it; no need to re-insert
    
    Run Code Online (Sandbox Code Playgroud)

    引用的行为与指针类似(即它们仅“指向”某个实例),但存在一些差异。例如,引用在其生命周期内始终指向同一个实例(您无法重新分配引用)。此外,它们的语法等于值,即不需要->

就我个人而言,如果您不需要在程序中的多个位置放置指向同一对象的指针,我更喜欢第三个选项。如果是这种情况,我们就说“共享”对象,这正是您想要使用“共享”指针的情况。第一个选项非常低级,应被视为“过时”。