智能指针有实际用例吗?

Are there real use cases for smart pointers?

我正在阅读 C++ 中的智能指针,令我惊讶的是,超过 99% 的给定示例实际上是相当糟糕的示例,因为在这些情况下可以避免动态分配。我同意仅在 STL 容器无法工作的情况下使用智能指针。例如,在动态数组 (std::vector) 中,性能很重要,因此最好在不使用任何智能指针的情况下拥有经过良好测试的代码。

我认为这是一个不好的例子,因为在这种情况下 unique_ptr 不是解决方案,但堆栈分配是正确的方法。

MyObject* ptr = new MyObject(); 
ptr->DoSomething(); 
delete ptr; 

那么 C++ 中的智能指针有哪些好的示例或用途?

换句话说,将指针的所有权转移到另一个对象需要什么样的设计模式?

I am surprised that more than 99% of the given examples are in fact fairly bad examples because in those cases dynamic allocation could be avoided

这可能是因为示例旨在超级简单。

So what could be good examples or uses for Smart Pointers in C++?

别管“善良”,而是考虑以下相关案例示例:

1。当你坚持不住筹码时

template <typename T>
std::unique_ptr<T[]> print_and_allocate(std::size_t n)
{
    std::cout << "Allocating " << n << " elements of size " << sizeof(T) << '\n';
    return std::make_unique<T[]>(n);
}

您不能在堆栈上执行分配,因为您在分配的元素被使用之前 returning。此外,您不能仅 return 单个构造或 std::array,因为事先不知道要分配的元素数量。

2。需要引用几个可能的 subclasses

之一
class A;
class B : public A { /* ... */ };
class C : public A { /* ... */ };

// ...

auto my_a = std::unique_ptr<A>(condition ? (A*) new B : (A*) new C);
my_a.some_virtual_method();

3。复杂的解除分配逻辑

指针不会告诉您 when/how 它需要 freed/deallocated。你可以做一个简单的假设(“我需要释放我从这个函数得到的指针”),但这已经建议在包装器 class 中表达你的假设。如果取消分配的条件更复杂,尤其是如果指针接收者不知道它们,那么以某种方式传达它们就变得至关重要。 std::shared_ptrstd::weak_ptr 是两种方法;另一个是 std::unique_ptrcustom deleter.

4。当无法保证未来的可用性时

当指针的提供者不能保证它会继续有效,但希望它可能会有效时 - 您需要某种包装器 class 来反映这一事实并确保您当你实际上不能时,不要试图取消引用指针。这就是 std::weak_ptr() 发挥作用的地方。


更一般地说:如果您之前出于某种原因需要分配内存并保存指针,并且没有它就不行 - 您很可能想改用智能指针。另见:

What is a smart pointer and when should I use one (answer).

So what could be good examples or uses for Smart Pointers in C++?

任何需要堆上资源的情况。

你是对的,在现实世界的场景中,大多数智能指针示例都是用堆栈分配编写的。但它们只是 - 简单的示例来演示 use/advantages 智能指针。

然而实际上,您不能将所有内容都放在堆栈上。一旦你需要在堆上动态分配内存,智能指针几乎总是比 new/delete.

的原始指针更好的选择。

在实际用例中,您实际上并不想关心内存管理。您不希望内存泄漏,因为您在某处忘记了一个 delete 。这就是智能指针派上用场的地方,因为它们解除了清理的责任。