我通常不是C ++开发人员。我通常的语言都是垃圾收集,他们为我工作,但C ++让我感兴趣。
我有一两个关于返回动态分配的对象或结构的问题。我的理解是它们必须动态分配,因此数据在堆中而不是堆栈中。如果我错了,请纠正我。
返回指针的最佳做法是什么?假设我正在编写一个库,如何在代码中指示是否应该删除返回的指针?如果我返回一个数组,我该如何返回数组的大小?
这些不是我在C#或javascript中必须面对的问题。这些问题都有两个方面:如果我使用其他人的库,我该寻找什么?
答案 0 :(得分:5)
C ++有一个叫做RAII的习语。对您来说意味着您不必担心清理,并且资源将在代码中的已定义点释放。
例如,在函数中创建一个数组并返回它。这是一个没有RAII的典型实现(另一个是调用者分配内存并将其传入):
int *makeIntArray(std::size_t length) {
return new int[length];
}
现在调用者需要记住释放这个内存。将其与RAII版本进行比较:
std::vector<int> makeIntArray(std::size_t length) {
return std::vector<int>(length);
}
当向量超出范围时,从此返回的内容将释放其内存,这取决于调用者。它还提供了size()
成员函数来获取元素的数量。
也就是说,最好在可能的情况下保持动态分配。如果您需要返回一个结构,比如说Str
,只需按值返回:
Str makeStr() {
return Str();
}
没有动态分配意味着没有额外的工作,无论是释放内存,还是将其包装成某种东西(在这种情况下是智能指针,如std::unique_ptr
)。
对于其他库,您需要阅读文档以确保您必须拥有它返回的内容。如果必须,您可以做的一件事就是从中制作出一个RAII对象。例如:
int *makeSomeInt(int value) {
return new int(value);
}
...
std::unique_ptr<int> myInt(makeSomeInt(5));
//memory freed when myInt goes out of scope
答案 1 :(得分:0)
我看到克里斯已经提供了一个很好的答案。添加的东西很少:
远离 代码中的动态内存分配。让动态内存分配(和解除分配)尽可能由库完成。 (参见上面vector
的示例。)
如果您必须自己进行动态内存分配,那么每个内存(即指针)都必须拥有所有者。应该构建和破坏内存的是所有者,其他人只能使用。
如果您使用的是C ++ 11,那么请熟悉unique_ptr
,这是您最常需要的。
来自Dr.Dobb s:
C ++ 11中有很多很棒的功能,但unique_ptr很突出 在代码卫生领域。简单地说,这是一个神奇的子弹 动态创建的对象。