我应该删除作为参数传递给函数的指针吗?
Should I delete pointer passed to a function as argument?
所以我正在阅读一些关于删除指针参数的 Stack Overflow 答案,尤其是这些 (1,2),因为我正在构建一个函数,它需要一个指针作为参数。
函数的简化版本如下:
void draw(Shape * b)
{
//Draws code....
}
不,我在这里感到困惑的是删除。例如,如果函数这样调用:
Shape * c;
draw(&c);
那我什么都不用删了。但是如果是这样的话:
draw(new Shape{});
那我不得不。所以基本上,我的问题是,如果在参数中使用 new
关键字,我应该如何删除。函数中没有可能抛出的异常,因此不需要 RAII。有任何想法吗?请不要提出任何涉及智能指针的建议,因为那是我已经要做的,这个问题是好奇心。另外,请知道该函数可以同时采用新运算符或现有指针,这基本上意味着我需要一种方法来区分两者。另外,对于我的链接:这些并没有真正回答我的问题,因为它们中的大多数只依赖于智能指针,或者一个调用或另一个。
basically meaning I need a way to differentiate between both.
不,你没有。在这种情况下,函数根本不应该在指针上调用 delete。函数的调用者有此信息,如果需要,它应该在指针上调用 delete,而不是函数本身。
简单的函数应该期望引用指针:
void draw(Shape *&p);
如果阻止:
Shape shape; // not pointer
draw(&shape);
来自:
draw(new Shape());
你可能会用到
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);
忽略智能指针或其他 RAII 解决方案的可能性:作为函数契约的一部分,必须记录函数是否拥有给定指针的所有权。
如果它取得所有权,函数负责删除它。调用者以后不得使用它。
您的示例函数称为 draw
。在那种情况下,我认为它不应该拥有所有权。画出形状就可以了。
没有什么可以说你不能删除作为函数参数传递的指针,但通常最好在与它们相同的上下文中删除堆对象已创建。
例如,我会考虑这个:
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
16=].
Now what I am confused about here is deletion.
这正是我们从不将原始指针作为参数传递的原因。
以下是您可能需要考虑的一些经验法则:
你不能改变我传给你的形状:
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);
所以我正在阅读一些关于删除指针参数的 Stack Overflow 答案,尤其是这些 (1,2),因为我正在构建一个函数,它需要一个指针作为参数。
函数的简化版本如下:
void draw(Shape * b)
{
//Draws code....
}
不,我在这里感到困惑的是删除。例如,如果函数这样调用:
Shape * c;
draw(&c);
那我什么都不用删了。但是如果是这样的话:
draw(new Shape{});
那我不得不。所以基本上,我的问题是,如果在参数中使用 new
关键字,我应该如何删除。函数中没有可能抛出的异常,因此不需要 RAII。有任何想法吗?请不要提出任何涉及智能指针的建议,因为那是我已经要做的,这个问题是好奇心。另外,请知道该函数可以同时采用新运算符或现有指针,这基本上意味着我需要一种方法来区分两者。另外,对于我的链接:这些并没有真正回答我的问题,因为它们中的大多数只依赖于智能指针,或者一个调用或另一个。
basically meaning I need a way to differentiate between both.
不,你没有。在这种情况下,函数根本不应该在指针上调用 delete。函数的调用者有此信息,如果需要,它应该在指针上调用 delete,而不是函数本身。
简单的函数应该期望引用指针:
void draw(Shape *&p);
如果阻止:
Shape shape; // not pointer
draw(&shape);
来自:
draw(new Shape());
你可能会用到
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);
忽略智能指针或其他 RAII 解决方案的可能性:作为函数契约的一部分,必须记录函数是否拥有给定指针的所有权。
如果它取得所有权,函数负责删除它。调用者以后不得使用它。
您的示例函数称为 draw
。在那种情况下,我认为它不应该拥有所有权。画出形状就可以了。
没有什么可以说你不能删除作为函数参数传递的指针,但通常最好在与它们相同的上下文中删除堆对象已创建。
例如,我会考虑这个:
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
16=].
Now what I am confused about here is deletion.
这正是我们从不将原始指针作为参数传递的原因。
以下是您可能需要考虑的一些经验法则:
你不能改变我传给你的形状:
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);