2

我通常不是 C++ 开发人员。我常用的语言都是垃圾收集的,它们为我工作,但 C++ 让我感兴趣。

关于返回动态分配的对象或结构,我有一两个问题。我的理解是它们必须动态分配,因此数据在堆中而不是堆栈中。如果我错了,请纠正我。

返回指针的最佳做法是什么?假设我正在编写一个库,我如何在代码中指示是否/何时应该删除返回的指针?如果我返回一个数组,我如何返回数组的大小?

这些不是我在 C# 或 javascript 中必须面对的问题。这些问题确实是双向的:如果我在使用别人的图书馆,我要寻找什么?

4

2 回答 2

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
于 2013-01-24T03:31:01.710 回答
0

我看到克里斯已经提供了一个很好的答案。有几件事要补充:

  • 远离在代码中分配动态内存。让动态内存分配(和释放)尽可能由库来完成。(见vector上面的例子。)

  • 如果你必须自己做动态内存分配,那么每个内存(即指针)都必须有一个所有者。内存的构造和销毁应该是所有者,其他人只能使用它。

  • 如果您使用的是 C++11,请熟悉unique_ptr,这是您最常需要的。

    来自Dobb 博士

    C++11 中有很多很棒的特性,但 unique_ptr 在代码卫生领域脱颖而出。简单地说,这是动态创建对象的灵丹妙药。

于 2013-01-24T04:15:18.573 回答