我应该删除作为参数传递给函数的指针吗?

时间:2016-08-24 13:29:44

标签: c++ pointers new-operator delete-operator

所以我正在阅读一些有关删除指针参数的Stack Overflow答案,特别是这些(12),因为我正在构建一个需要指针作为参数的函数。

该功能的简化版本如下:

void draw(Shape * b)
{
    //Draws code....
}

不,我在这里感到困惑的是删除。例如,如果像这样调用函数:

Shape * c;
draw(&c);

然后我不必删除任何内容。但如果是这样的话:

draw(new Shape{});
然后我必须这样做。所以基本上,我的问题是,如果在参数中使用new关键字,我该如何删除呢?没有可能在函数中抛出的异常,因此不需要RAII。有任何想法吗?请不要提出任何涉及智能指针的内容,因为这就是我已经做过的事情,这个问题就是好奇心。另外,请回答知道函数可以同时使用新运算符或现有指针,这基本上意味着我需要一种方法来区分两者。另外,对于我的链接:这些并不能真正回答我的问题,因为大多数问题都依赖于智能指针,或者一个电话或另一个电话。

6 个答案:

答案 0 :(得分:8)

  

现在我对此感到困惑的是删除。

这正是我们永远不会将原始指针作为参数传递的原因。

以下是您可能需要考虑的一些经验法则:

  1. 你可能不会改变我传给你的形状:

    void draw(const Shape& shape);

  2. 您可以改变形状,但我保留对它的所有权:

    void draw(Shape& shape);

  3. 请使用我的形状副本:

    void draw(Shape shape);

  4. 请取消这种形状的所有权:

    void draw(std::unique_ptr<Shape> shape);

  5. 让我们分享这个形状:

    void draw(std::shared_ptr<const Shape> shape);

答案 1 :(得分:5)

您可以使用

void draw(std::observer_ptr<Shape> shape)

void draw(Shape& shape)

void draw(Shape * shape)

明确draw不回收所有权。

并在回收时在签名中使用智能指针。

void Take(std::unique_ptr<Shape> shape);

void Take(std::shared_ptr<Shape> shape);

答案 2 :(得分:4)

没有什么可以说你不能删除作为函数参数传递的指针,但通常最好在创建它们的相同上下文中删除堆对象。

例如,我会考虑这个:

Shape * pShape = new Shape(...);

draw(pShape);

delete pShape;

比这更好:

draw(new Shape(...));  // Did the shape get deleted? Who knows...

后一个例子也阻止你处理draw()因任何原因无法调用delete的情况,可能会造成内存泄漏。

我强烈建议使用智能指针(例如unique_ptr<>shared_ptr<>)来处理指针的生命周期。但是如果你绝对不能,请确保记录你的函数并声明你正在传递指向函数的指针的所有权,并且调用者在调用{{pShape之后不应该期望能够使用draw() 1}}。

答案 3 :(得分:2)

  

基本上意味着我需要一种方法来区分两者。

不,不。在这种情况下,函数不应该在指针上调用delete。函数的调用者有这个信息,如果需要,它应该在指针上调用delete,而不是函数本身。

答案 4 :(得分:1)

忽略智能指针或其他RAII解决方案的可能性:作为函数契约的一部分,必须记录该函数是否取得给定指针的所有权。

如果它拥有所有权,则该函数负责删除它。调用者以后不得使用它。

您的示例函数名为draw。在那种情况下,我认为它不应该取得所有权。只需绘制形状并留下即可。

答案 5 :(得分:0)

简单的函数应该期望引用指针:

void draw(Shape *&p);

如果阻止:

Shape shape; // not pointer
draw(&shape);

和来自:

draw(new Shape());