c++ - std::shared_ptr 为空但不为空
问题描述
http://www.cplusplus.com/reference/memory/shared_ptr/说
不拥有任何指针的 shared_ptr 称为空 shared_ptr。不指向任何对象的 shared_ptr 称为 null shared_ptr 并且不应被取消引用。请注意,空的 shared_ptr 不一定是空的 shared_ptr,空的 shared_ptr 也不一定是空的 shared_ptr。
我是否能够创建一个空的 std::shared_ptr,即一个不拥有任何东西但不为空的 std::shared_ptr,即包含有效负载?
用例是将“遗留”代码与现代指针结合起来:鉴于foo
不改变调用语法,
void foo(const MyClass* p) {
if (p == nullptr) {
auto defaultObject = std::make_shared<MyClass>("some", "parameters");
defaultObject->doSomething();
...
defaultObject->doSomethingElse();
// The default object must be destroyed again
} else {
p->doSomething();
...
p->doSomethingElse();
// p must not be destroyed, its memory is managed somewhere else
}
}
是否有doNotOwnButStillPointTo()
允许这样做的实现:
void foo(const MyClass* p) {
std::shared_ptr<MyClass> wrapper;
if (p == nullptr) {
// Create a default object
wrapper = std::make_shared<MyClass>("some", "parameters");
} else {
wrapper = doNotOwnButStillPointTo(p);
}
wrapper->doSomething();
...
wrapper->doSomethingElse();
// p mus not be destroyed, the default object (if created) shall be
}
或者,为了不陷入XY-Problem,是否有不同的智能指针可用或根本没有?
- 但是,我想补充一点,该行
std::make_shared<MyClass>("some", "parameters")
实际上是对创建 shared_ptr 的更复杂函数的调用。我想保留这个功能并使用它的结果
解决方案
有shared_ptr
一个删除器。这是一个销毁底层对象的多态过程。您可能有一个空的删除器:
void foo(const MyClass* p) {
std::shared_ptr<MyClass> wrapper;
if (p == nullptr) {
// Create a default object
wrapper = std::make_shared<MyClass>("some", "parameters");
} else {
wrapper = std::shared_ptr<MyClass>(p, [](MyClass*){});
}
wrapper->doSomething();
...
wrapper->doSomethingElse();
// p mus not be destroyed, the default object (if created) shall be
}
然而,这会导致糟糕的设计。回到问题XY:目的是什么?有人可能会将对象作为原始指针传递给您(但可能会传递一个 nullptr)。如果提供的是 nullptr 而不是真实对象,您希望创建一个本地对象。您可能希望防止内存泄漏。好的。
void foo(const MyClass* p) {
std::shared_ptr<MyClass> local;
if (p == nullptr) {
// Create a default object
local = std::make_shared<MyClass>("some", "parameters");
p = local.get();
}
// p is always valid, local will always be destroyed (if exists)
p->doSomething();
...
p->doSomethingElse();
}
推荐阅读
- java - 在使用 Jax-Rs 调用 RestApi 时返回用户定义的类对象时出错
- docusignapi - 如何在 Docusign 嵌入式用户签名体验中启用/禁用完成按钮?
- xaml - 如何在 UWP 中设置 RatingControl 星星的颜色?
- xml - 处理指令中的实体发生变化
- javascript - 对 ng-options 对象的更改未更新为 html
- java - 如何将 SQL 数据映射到 Java JSON 对象和 JSON 数组?
- node.js - 无法在节点 js 中连接 MsSql 数据库
- javascript - 我在使用 setInterval 和类方法时遇到了很多麻烦
- javascript - 喜欢用单个复选框 php ajax 不喜欢
- javascript - 有没有办法将刷新持久性添加到进度条?