所以我正在阅读一些有关删除指针参数的Stack Overflow答案,特别是这些(1,2),因为我正在构建一个需要指针作为参数的函数。
该功能的简化版本如下:
void draw(Shape * b)
{
//Draws code....
}
不,我在这里感到困惑的是删除。例如,如果像这样调用函数:
Shape * c;
draw(&c);
然后我不必删除任何内容。但如果是这样的话:
draw(new Shape{});
然后我必须这样做。所以基本上,我的问题是,如果在参数中使用new
关键字,我该如何删除呢?没有可能在函数中抛出的异常,因此不需要RAII。有任何想法吗?请不要提出任何涉及智能指针的内容,因为这就是我已经做过的事情,这个问题就是好奇心。另外,请回答知道函数可以同时使用新运算符或现有指针,这基本上意味着我需要一种方法来区分两者。另外,对于我的链接:这些并不能真正回答我的问题,因为大多数问题都依赖于智能指针,或者一个电话或另一个电话。
答案 0 :(得分:8)
现在我对此感到困惑的是删除。
这正是我们永远不会将原始指针作为参数传递的原因。
以下是您可能需要考虑的一些经验法则:
你可能不会改变我传给你的形状:
void draw(const Shape& shape);
您可以改变形状,但我保留对它的所有权:
void draw(Shape& shape);
请使用我的形状副本:
void draw(Shape shape);
请取消这种形状的所有权:
void draw(std::unique_ptr<Shape> shape);
让我们分享这个形状:
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());