C++:在函数中使用调用者的局部变量是否安全?

发布于 2024-11-23 16:32:25 字数 610 浏览 6 评论 0原文

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

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++ 标准,上述概念是否能按预期工作?为什么(不)?
  • 谨慎小心地这样做是否被认为是不好的做法?

I think it's best if I describe the situation using a code example:

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();
}

And here come my straightforward questions:

  • Is the above concept guranteed, by C and C++ standards, to work as expected? Why (not)?
  • Is this considered doing this, sparingly and with care, bad practice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

〆一缕阳光ご 2024-11-30 16:32:25

根据 C 和 C++ 标准,上述概念是否能保证按预期工作?为什么(不)?

是的,它会按预期工作。 someInstance 可通过 MyFuncA 范围使用。对 MyFuncB 的调用就在该范围内。

谨慎谨慎地这样做是否被认为是不好的做法?

不明白为什么。

Is the above concept guranteed, by C and C++ standards, to work as expected? Why (not)?

Yes, it will work as expected. someInstance is available through the scope of MyFuncA. The call to MyFuncB is within that scope.

Is this considered doing this, sparingly and with care, bad practice?

Don't see why.

萌面超妹 2024-11-30 16:32:25

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

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

I don't see any problem in actually using the pointer you were passed to call functions on the object. As long as you call public methods of MyClass, everything remains valid C/C++.

The actual instance you create at the beginning of MyFuncA() will get destroyed at the end of MyFuncA(), and you are guaranteed that the instance will remain valid for the whole execution of MyFuncB() because someInstance is still valid in the scope of MyFuncA().

偏爱自由 2024-11-30 16:32:25

是的,它会起作用。您传递给 MyFuncB 的指针是在堆栈上还是在堆上(在本例中)并不重要。

关于不良实践部分,您可能可以从两个方面进行争论。总的来说,我认为这很糟糕,因为如果出于任何原因,任何位于 MyFuncA 之外的对象获取了对象引用,那么它稍后就会惨死,并导致有时很难跟踪错误。这完全取决于对象在 MyFuncB 中的使用范围。尤其是当它开始涉及另一个第三类时,它可能会变得混乱。

Yes it will work. It does not matter if the pointer you pass into MyFuncB is on the stack or on the heap (in this specific case).

In regards for the bad practice part you can probably argue both ways. In general it's bad I think because if for any reason any object which is living outside of MyFuncA gets hold of the object reference then it will die a horrible death later on and cause sometime very hard to track bugs. It rewally depends how extensive the usage of the object becomes in MyFuncB. Especially when it starts involving another 3rd class it can get messy.

和影子一齐双人舞 2024-11-30 16:32:25

其他人回答了基本问题,“是的,这是合法的”。在缺乏更好的架构的情况下,很难将其称为好或坏实践。但我会尝试从哲学角度探讨您似乎遇到的关于指针、对象生命周期和函数调用之间的期望的更广泛问题...

在 C++ 语言中,没有内置方法将指针传递给函数并“强制”在通话完成后它不会将其收起。由于 C++ 指针默认是“弱引用”,所以指向的对象可能会从下面消失您将其传递给的人。

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

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

这些旨在专门向接收者编码“偏执”,即其所持有的物体可能会从其下方消失。任何取消引用某种类型的人都会意识到有些事情已经发生了,他们必须根据设计合同采取适当的谨慎措施。

此外,存在诸如共享指针之类的抽象,这向接收者发出了不同的理解。将其中之一传递给他们,让他们有权在需要的时间内保持对象处于活动状态,从而为您提供诸如垃圾收集之类的东西:

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

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

(使用 C++ 而不是其他语言的主要原因之一是,您可以使用丰富的工具来完成此类很酷的事情,而无需太多的运行时成本!)

Others have answered the basic question, with "yeah, that's legal". And in the absence of greater architecture it is hard to call it good or bad practice. But I'll try and wax philosophical on the broader question you seem to be picking up about pointers, object lifetimes, and expectations across function calls...

In the C++ language, there's no built-in way to pass a pointer to a function and "enforce" that it won't stow that away after the call is complete. And since C++ pointers are "weak references" by default, the objects pointed to may disappear out from under someone you pass it to.

But explicitly weak pointer abstractions do exist, for instance in Qt:

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

These are designed to specifically encode the "paranoia" to the recipient that the object it is holding onto can disappear out from under it. Anyone dereferencing one sort of realizes something is up, and they have to take the proper cautions under the design contract.

Additionally, abstractions like shared pointer exist which signal a different understanding to the recipient. Passing them one of those gives them the right to keep the object alive as long as they want, giving you something like garbage collection:

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

These are only some options. But in the most general sense, if you come up with any interesting invariant for the lifetimes of your object...consider not passing raw pointers. Instead pass some pointer-wrapping class that embodies and documents the rules of the "game" in your architecture.

(One of major the reasons to use C++ instead of other languages is the wealth of tools you have to do cool things like that, without too much runtime cost!)

ヅ她的身影、若隐若现 2024-11-30 16:32:25

我认为除了你所说的释放对象或以其他方式破坏其状态的东西之外应该没有任何问题。我认为无论发生什么意外的事情都与以这种方式使用该类无关。 (当然,生活中没有什么是可以保证的,但是类的目的是传递和操作,无论它是局部变量还是我认为不相关的其他变量。)

您无法做的一件事是保留引用当 MyFuncA() 返回时,类超出范围,但这只是作用域规则的本质。

i don't think there should be any problem with that barring, as you say, something that frees the object, or otherwise trashes its state. i think whatever unexpected things happen would not have anything to do with using the class this way. (nothing in life is guaranteed of course, but classes are intended to be passed around and operated on, whether it's a local variable or otherwise i do not believe is relevant.)

the one thing you would not be able to do is keep a reference to the class after it goes out of scope when MyFuncA() returns, but that's just the nature of the scoping rules.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文