1

在 C++ 中,假设 Helper 类中有一个方法,它返回一个指向另一个对象的指针。除了方法签名和返回对象的类型外,我没有关于此方法的更多信息。在这种情况下如何进行内存管理?

我试图在下面使用智能指针作为这个函数:

void f() {
   auto_ptr<SomeClass> p_someClass = p_Helper->getSomeclass();
   p_someClass->doSomething();
}

一旦 f() 超出范围,分配给 p_someClass 的内存就会被释放。但是,如果 getSomeclass() 不分配新内存而只是返回一个“单例”指针(并且 p_Helper 也是单例)怎么办?那么下一次调用 p_Helper->getSomeclass() 就会遇到麻烦。

处理这个问题的常用方法是什么,尤其是当 Helper 类的文档很少时?

4

5 回答 5

3

助手类的文档说什么?那是终极问题。你不能在不指定其生命周期的情况下返回指针或引用:如果它是指向类内部某些东西的指针,它可能是类对象的生命周期,但它也可能具有静态生命周期(直到程序结束——这是将字符串文字返回为 ) 的函数的情况char const*,它可能有一些较短的生命周期(例如 operator[]由标准库容器返回的引用),或者助手可能希望您删除它。然而,后者在纯 C++ 中应该很少见。在这种情况下,惯例是返回std::auto_ptr(或 std::unique_ptr如果你有一个非常现代的编译器)。(在 C 中,经常记录必须通过调用返回它的库中的特定函数来释放返回的指针。如果没有析构函数,您必须在最后做一些事情来重新获得控制权。)

在没有文档的情况下,我很想说这个库不可用。仍然......假设它指向内部的东西并且具有类的生命周期可能是最合理的猜测;这是程序员最容易忘记记录的情况。删除它,或者把它放在一个将删除它的智能指针中,可能不是一个好主意:关于所有权问题已经说得够多了,如果你应该删除它,类作者似乎不太可能无法记录这一事实. (但是请注意,即使您不应该删除它,生命周期问题仍然存在。)

于 2012-07-18T07:30:07.137 回答
2

如果你不是 p_Helper 类的作者,首先:

单例通常没有公共析构函数,因此在这种情况下不会编译。

其次,如果您“只是得到”一个没有任何进一步信息的裸指针,则无法知道是否可以删除它。该信息需要在文档中提供,以便您使用该函数/方法。

如果您正在设计p_Helper,则让它返回智能指针,而不是裸指针。如果该方法为每个调用创建一个新资源,我建议unique_ptr,看看这里:unique_ptr 和 shared_ptr 之间的差异

于 2012-07-18T07:13:04.417 回答
1

这种情况的典型方法是使用引用计数,这样的智能指针shared_ptr通常会处理所有合理的情况。

于 2012-07-18T07:13:27.150 回答
1

在这种情况下,您可以使用原始指针。

void f() {
   SomeClass *p_someClass = p_Helper->getSomeclass();
   p_someClass->doSomething();
}
于 2012-07-18T07:14:32.980 回答
1

您可以进行快速测试并比较两次调用 p_Helper->getSomeclass(); 所返回的指针;

bool do_not_delete =  p_Helper->getSomeclass() ==  p_Helper->getSomeclass();

如果两个指针相等,您很可能会得到一个指针,该指针是一个(可能是可选的)引用。

hth 托斯滕

于 2012-07-18T07:39:34.410 回答