C ++:在函数中安全使用调用者的本地人?

时间:2011-07-12 01:10:51

标签: c++ pointers stack local

我认为最好是使用代码示例描述情况:

int MyFuncA()
{
    MyClass someInstance;
    //<Work with and fill someInstance...>

    MyFuncB( &someInstance )
}

int MyFuncB( MyClass* instance )
{
    //Do anything you could imagine with instance, *except*:
    //* Allowing references to it or any of it's data members to escape this function
    //* Freeing anything the class will free in it's destructor, including itself

    instance->DoThis();
    instance->ModifyThat();
}

这是我直截了当的问题:

  • 根据C和C ++标准,上述概念是否符合预期?为什么(不是)?
  • 这是否被认为是这样做,谨慎而谨慎,不好的做法?

5 个答案:

答案 0 :(得分:1)

  

根据C和C ++标准,上述概念是否符合预期?为什么(不是)?

是的,它会按预期工作。 someInstance可以通过MyFuncA的范围获得MyFuncB。对{{1}}的调用是在该范围内。

  

这是否被认为是这样做,谨慎而谨慎,不良做法?

不明白为什么。

答案 1 :(得分:1)

在实际使用传递给对象上的函数的指针时,我没有看到任何问题。只要你调用MyClass的公共方法,一切都是有效的C / C ++。

您在MyFuncA()开头创建的实际实例将在MyFuncA()结束时被销毁,并且您可以保证该实例在MyFuncB()的整个执行期间保持有效因为someInstanceMyFuncA()范围内仍然有效。

答案 2 :(得分:1)

是的,它会起作用。传入MyFuncB的指针是在堆栈上还是在堆上(在这种特定情况下)并不重要。

关于不良练习部分,你可以双向争论。一般来说,我认为这很糟糕,因为如果出于任何原因,任何生活在MyFuncA之外的对象都会抓住对象引用,那么它将在以后死于可怕的死亡,并且有时很难跟踪错误。它在很大程度上取决于对象在MyFuncB中的使用范围。特别是当它开始涉及另一个第三类时,它可能会变得混乱。

答案 3 :(得分:1)

其他人回答了基本问题,“是的,这是合法的”。在缺乏更大的架构的情况下,很难将其称为好的或坏的做法。但是我会尝试在更广泛的问题上进行哲学思考,你似乎对函数调用中的指针,对象生命周期和期望有所了解......

在C ++语言中,没有内置方法可以将指针传递给函数,并且“强制”它在调用完成后不会将其存放起来。由于C ++指针默认为“weak references"”,因此指向的对象可能会从您传递给它的人身上消失。

显式弱指针抽象确实存在,例如在Qt中:

http://doc.qt.nokia.com/latest/qweakpointer.html

这些设计用于专门对收件人编码“偏执狂”,使其所持有的对象可以从其下方消失。任何解除引用某种东西的人都会意识到某些东西已经出现,他们必须在设计合同下采取适当的警告。

此外,存在共享指针之类的抽象,这表明对接收者有不同的理解。传递它们中的一个使它们有权在对象保持活着的时候,给你一些垃圾收集:

http://doc.qt.nokia.com/4.7-snapshot/qsharedpointer.html

这些只是一些选择。但是从最普遍的意义上说,如果你在对象的生命周期中提出任何有趣的不变量...考虑不要传递原始指针。而是传递一些指针包装类,它体现并记录了架构中“游戏”的规则。

(使用C ++而不是其他语言的主要原因之一是你必须做很多酷工具的工具,没有太多的运行时成本!)

答案 4 :(得分:0)

我认为,正如你所说,禁止对象释放或以其他方式破坏其状态的禁令应该没有任何问题。我认为无论发生什么意想不到的事情都不会与这种方式使用课程有任何关系。 (当然,生活中没有任何保证,但课程是为了传递和操作,无论是本地变量还是其他我认为不相关的。)

当MyFuncA()返回时,你不能做的一件事是在它超出范围后保留对类的引用,但这只是范围规则的本质。