当我不知道如何分配 `ptr` 时,`std::unique_ptr<Base>(ptr)` 的销毁策略?
Destruction policy for `std::unique_ptr<Base>(ptr)` when I don't know how `ptr` was allocated?
另一个 "modern C++" 初学者问题。我似乎对如何正确使用智能指针/智能指针销毁策略有一些误解。
struct Base {
virtual Base* clone() const = 0;
virtual ~Base() { }
};
void clone_and_use(const Base &original) {
auto clone = std::unique_ptr<Base>(original.clone());
… // do something with `clone`
}
据我所知,当 clone
超出范围时,由于 std::default_delete<Base>
使用的销毁策略,指向的内存将是 delete
d 17=](这似乎等同于 std::unique_ptr<Base, std::default_delete<Base>>
)。
如果 original.clone()
返回一个指向 不是 分配给 new
的内存的指针怎么办?显然,标准的 std::default_delete<Base>
销毁策略是不合适的——delete
只能与 new
一起使用,但不能与 new[]
、malloc
或其他任何东西一起使用——我应该在创建 clone
智能指针时指定一个不同的销毁策略……但我会指定哪个?
auto clone = std::unique_ptr<Base, ?>(original.clone());
// ^
我猜我必须扩展 Base
这样我就可以简单地要求任何派生类型提供适合其 clone()
实现的销毁策略,但我不确定我会怎么做。
谁能告诉我怎么做:
- 定义
Base
接口,使其可以支持 clone()
方法,而不会导致泄漏或错误释放内存;和
- 如何正确使用智能指针销毁策略(如果在本例中有必要)?
你的clone()
应该return一个合适的智能指针,即
virtual std::unique_ptr<Base> clone() {
...
}
这样就避免了歧义。
只需要 Base
定义一个 clone
方法,returns 具有正确删除器的智能指针。
void clone_and_use(const Base& original) {
auto clone = original.Clone();
... // do something with `clone`
}
std::unique_ptr<Base, BaseDeleter> Clone() const {
return std::unique_ptr<Base, BaseDeleter>(new Base(this));
}
或者,您可以为您的类型覆盖 std::default_delete
。
namespace std
{
template<>
class default_delete<Base>
{
public:
void operator()(Base* ptr)
{
// Do delete operation on `ptr`
}
};
}
What if original.clone() returned a pointer to memory that was not allocated with new?
如果您不知道如何解除分配它,则无论有无任何智能指针的帮助,您都无法解除分配它class。因此,您不能以任何形式取得它的所有权。
How to properly work with smart pointer destruction policies
您不能使用未知策略。如何在 your class 中正确使用智能指针销毁策略?简单:它是 你的 class。让政策为人所知。决定一项政策并记录您的决定,因此编写派生 class 的每个人都必须遵守。或者,将输出参数 std::function& deletePolicy
添加到 clone
,然后将 clone
包装在 returns 和 unique_ptr
.
的便利函数中
另一个 "modern C++" 初学者问题。我似乎对如何正确使用智能指针/智能指针销毁策略有一些误解。
struct Base {
virtual Base* clone() const = 0;
virtual ~Base() { }
};
void clone_and_use(const Base &original) {
auto clone = std::unique_ptr<Base>(original.clone());
… // do something with `clone`
}
据我所知,当 clone
超出范围时,由于 std::default_delete<Base>
使用的销毁策略,指向的内存将是 delete
d 17=](这似乎等同于 std::unique_ptr<Base, std::default_delete<Base>>
)。
如果 original.clone()
返回一个指向 不是 分配给 new
的内存的指针怎么办?显然,标准的 std::default_delete<Base>
销毁策略是不合适的——delete
只能与 new
一起使用,但不能与 new[]
、malloc
或其他任何东西一起使用——我应该在创建 clone
智能指针时指定一个不同的销毁策略……但我会指定哪个?
auto clone = std::unique_ptr<Base, ?>(original.clone());
// ^
我猜我必须扩展 Base
这样我就可以简单地要求任何派生类型提供适合其 clone()
实现的销毁策略,但我不确定我会怎么做。
谁能告诉我怎么做:
- 定义
Base
接口,使其可以支持clone()
方法,而不会导致泄漏或错误释放内存;和 - 如何正确使用智能指针销毁策略(如果在本例中有必要)?
你的clone()
应该return一个合适的智能指针,即
virtual std::unique_ptr<Base> clone() {
...
}
这样就避免了歧义。
只需要 Base
定义一个 clone
方法,returns 具有正确删除器的智能指针。
void clone_and_use(const Base& original) {
auto clone = original.Clone();
... // do something with `clone`
}
std::unique_ptr<Base, BaseDeleter> Clone() const {
return std::unique_ptr<Base, BaseDeleter>(new Base(this));
}
或者,您可以为您的类型覆盖 std::default_delete
。
namespace std
{
template<>
class default_delete<Base>
{
public:
void operator()(Base* ptr)
{
// Do delete operation on `ptr`
}
};
}
What if original.clone() returned a pointer to memory that was not allocated with new?
如果您不知道如何解除分配它,则无论有无任何智能指针的帮助,您都无法解除分配它class。因此,您不能以任何形式取得它的所有权。
How to properly work with smart pointer destruction policies
您不能使用未知策略。如何在 your class 中正确使用智能指针销毁策略?简单:它是 你的 class。让政策为人所知。决定一项政策并记录您的决定,因此编写派生 class 的每个人都必须遵守。或者,将输出参数 std::function& deletePolicy
添加到 clone
,然后将 clone
包装在 returns 和 unique_ptr
.