我应该使用 unique_ptr 作为字符串吗?

Should I use unique_ptr for a string?

我是 C++ 新手。我听说使用 unique_ptr / shared_ptr 是引用堆上分配的数据的“方法”。因此,使用 unique_ptrs 而不是 std::strings 有意义吗?

不需要使用 std::unique_ptr or std::shared_ptr for a std::string

您不必为简单的 std::string.

分配内存
std::string str = "abc";

就这么简单。不需要内存分配,因为 std::string 自己管理 'real' 字符串。


有些情况可能会导致使用指针,尽管它很可能是 class/struct 实例。

例如考虑使用

std::unique_ptr<MyClass> p;

而不是

MyClass *p;

如果可能的话。

您通常不需要指向字符串的指针,就像您通常不需要指向整数的指针一样。您可以只存储字符串值,也可以传递字符串值等。

但是如果您处于需要指向字符串的指针的特殊情况,那么是的,std::unique_ptr<std::string>std::shared_ptr<std::string>std::string* 更好。

你为什么要这样做?

std::string 对象自行管理 "contained" 字符串(内存字节)的生命周期。

由于您是 C++ 新手。在你的 function / class 方法中,我会建议你在堆栈上创建你的对象: 像这样:

  std::string s;

相对于使用堆:

 std::string* s = new std::string();

当您的对象超出范围时,在堆栈上创建的对象将被销毁。所以不需要智能指针。

你可以关注这个link了解更多:http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/

std::unique_ptr确保指向的对象不会被意外复制并正确删除。 由于您应该尽可能避免动态分配,因此您可以简单地将 std::string 作为 class 的成员。如果它是一个返回值,正如已经指出的那样,字符串 class 足够聪明,可以安全地正确移动资源。 你不需要保证一个字符串是唯一的,我的意思是,不存在副本,所以唯一的 ptr 只是一个太强的约束。 KIS 规则:保持简单。

通常,默认情况下,答案是否定的,正如其他人所建议的那样。然而 - 有时,答案可能自相矛盾地是“可能是”!怎么会?

  • 使用 std::string,您无法控制缓冲区的分配方式、时间和分配者。虽然如果您使用不同的分配器 (std::basic_string<char, MyAllocatorType>),这会有所缓解 - 结果 class 是 not std::string;并且通常不会被采用 std::string 的函数所接受。仅仅为了这个目的而进入分配器可能没有意义。
  • 更具体地说,您可以允许将 unique-pointer-based 字符串 class 创建为现有缓冲区的拥有包装器。
  • 现在我们可以使用 string_view - 它们甚至在 C++20 的标准中 (std::string_view) - 你不必重写整个字符串 class 用于 unique-pointer-based 字符串;您所需要的只是在其上创建一个字符串视图,使用原始指针和以字节为单位的大小(如果您想要更好的 null-termination 安全性,则大小为 1。)如果您确实想要 std::string 方法尽管如此,它们还是 one-liners,例如
    std::string_view view() const { 
         return std::string_view{uptr_.get(), size_}; 
    }
    substr(size_type pos = 0, size_type count = npos) const { 
         return view().substr(pos, count); 
    }
    
  • 如果您想更新字符串 in-place,同时保持其大小 - std::string 将不适合您:要么它完全不变,要么大小和内容都可变。