删除参考

New*_*lls 25 c++

这有效吗?可接受的做法?

typedef vector<int> intArray;

intArray& createArray()
{
    intArray *arr = new intArray(10000, 0);

    return(*arr);
}


int main(int argc, char *argv[])
{

    intArray& array = createArray();

    //..........

    delete &array;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 55

代码的行为将是您的预期行为.现在,问题在于,虽然您可能认为编程是关于为编译器编写要处理的内容,但是编写其他程序员(或将来的某些程序员)能够理解并能够维护的东西也同样重要.在许多情况下,您提供的代码等同于使用指针编译器,但对于其他程序员来说,它只是潜在的错误来源.

引用意味着是在其他地方管理的对象的别名.一般来说,当遇到人们时会感到惊讶delete &ref,并且在大多数情况下程序员不会期望必须delete在引用的地址上执行,所以将来有人可能会将该函数称为忘记删除而你会有内存泄漏.

在大多数情况下,通过使用智能指针可以更好地管理内存(如果你不能使用像std::vectors 这样的其他高级结构).通过将指针隐藏在引用后面,您使得在返回的引用上使用智能指针变得更加困难,因此您无法帮助用户更难以使用您的界面.

最后,引用的好处是,当您在代码中读取它们时,您知道对象的生命周期在其他地方被管理,您不必担心它.通过使用引用而不是指针,您基本上会回到单个解决方案(以前仅在C指针中),并且必须特别注意所有引用以确定是否必须在那里管理内存,而不是意味着更多的努力,更多的时间来考虑内存管理,减少担心实际问题的时间 - 由于额外的异常代码,人们越来越习惯用指针查找内存泄漏,并期望没有引用.

简而言之:通过引用保存的内存会隐藏用户处理内存的要求并使其更难以正确执行.


Mar*_*som 14

是的,我认为它会起作用.但是如果我在我工作的任何代码中看到类似的东西,我会把它撕掉并立即重构.

如果要返回已分配的对象,请使用指针.请!

  • 可以说,他们可能希望将其包装在适当的智能指针中,以使其异常安全。 (2认同)
  • @Steven Sudit,我的做法一直是返回原始指针,因为它允许最大的灵活性.但是我链接到的那个问题的答案表明,即使考虑到Boost中的选择,auto_ptr也具有相同的灵活性.它是标准的一部分这一事实使它成为一个明智的选择. (2认同)
  • 当然,现在值得一提的是,根据情况,`auto_ptr` 已被弃用,取而代之的是它的高级替代品,`unique_ptr` 或 `shared_ptr`。 (2认同)

Bil*_*eal 13

这是有效的...但我不明白为什么你想要这样做.这不是例外的安全,std::vector无论如何都会为你管理内存.为什么new呢?

编辑:如果你从一个函数返回新的内存,你应该返回指针,以免你的函数头的用户爆炸.


utn*_*tim 5

这是有效的吗?

是的。

一种可以接受的做法?

不。

这段代码有几个问题:

  • 为最不令人惊讶的行为而设计的准则被打破了:您返回“看起来像”对象但必须由客户端代码删除的东西(这应该意味着一个指针 - 引用应该是始终指向有效对象的东西)。

  • 您的分配可能会失败。即使你在分配函数中检查结果,你会返回什么?无效参考?在这种情况下,您是否依赖分配抛出异常?

作为设计原则,请考虑创建一个负责管理对象生命周期的 RAII 对象(在本例中为智能指针),或者在创建它的同一抽象级别删除该指针:

typedef vector<int> intArray;

intArray& createArray()
{
    intArray *arr = new intArray(10000, 0);

    return(*arr);
}

void deleteArray(intArray& object)
{
    delete &object;
}

int main(int argc, char *argv[])
{
    intArray& array = createArray();
    //..........
    deleteArray(array);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这种设计提高了编码风格的一致性(分配和释放是隐藏的,并在同一抽象级别实现),但通过指针工作仍然比通过引用更有意义(除非动态分配的对象必须保留实现细节)出于某些设计原因)。