【问题标题】:Keep object and reference to an object created inside a function保留对象和对在函数内部创建的对象的引用
【发布时间】:2013-11-06 13:28:33
【问题描述】:

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

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

map<string,MyObject*> myMap;

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

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

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

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

【问题讨论】:

  • 为什么不能在地图中存储对象?这将大大简化事情。
  • 你为什么不用objPtr = new MyObject(); 而不是MyObject obj1(); objPtr = &amp;obj1; 呢?这会在堆上创建超出函数范围的对象。但是,在使用完对象和地图后,您需要删除对象。在您的示例中,对象是在堆栈上创建的,并在函数完成后被删除。
  • 您可能想了解new 关键字。
  • 您的意思可能是MyObject obj1;?因为您的代码行MyObject obj1(); 将定义a function pointer variable

标签: c++


【解决方案1】:

您可以动态地实例化您的对象。

MyObject* objPtr = new MyObject;

但是当你不再使用这个实例时不要忘记删除它

delete objPtr;

【讨论】:

  • 您必须小心删除 objPtr,因为它会使存储在地图中的指针无效。
【解决方案2】:

除非您有充分的理由不这样做,否则在地图中存储对象可能更简单:

map<string, MyObject> myMap;

然后:

void myFunction(){
  ...
  myMap.insert(std::make_pair("xxxx", MyObject()));
  ...
} 

【讨论】:

  • 我刚刚做了,它解决了问题...谢谢
【解决方案3】:

代码行

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
    

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

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

【讨论】:

  • +1 用于使用shared_ptr,但您能指出这仅适用于最新标准吗?
  • @MKroehnert 谢谢,我添加了评论。
  • 非常感谢 leemes,只是存储对象而不是指针解决了所有问题......您的解释非常有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多