我应该为字符串使用unique_ptr吗? 我是C++新手。我听说使用unique\u ptr/shared\u ptr是引用堆上分配的数据的“方法”。因此,使用unique_ptrs而不是std::strings有意义吗?

我应该为字符串使用unique_ptr吗? 我是C++新手。我听说使用unique\u ptr/shared\u ptr是引用堆上分配的数据的“方法”。因此,使用unique_ptrs而不是std::strings有意义吗?,c++,c++11,unique-ptr,stdstring,C++,C++11,Unique Ptr,Stdstring,无需使用or来表示 您不必为一个简单的应用程序分配内存 就这么简单。不需要内存分配,因为它自己管理“real”字符串 有些情况可能会导致使用指针,尽管它可能是类/结构实例 例如考虑使用 std::unique_ptr<MyClass> p; 如果可能的话。您通常不需要指向字符串的指针,就像您通常不需要指向整数的指针一样。您可以只存储字符串值,也可以传递字符串值,等等 但是如果您处于需要字符串指针的特殊情况,那么是的,std::unique_ptr或std::shared_ptr比

无需使用or来表示

您不必为一个简单的应用程序分配内存

就这么简单。不需要内存分配,因为它自己管理“real”字符串


有些情况可能会导致使用指针,尽管它可能是类/结构实例

例如考虑使用

std::unique_ptr<MyClass> p;

如果可能的话。

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


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

你为什么要这么做

string对象自己管理“包含”字符串(内存字节)的生存时间

因为你是C++新手。在函数/类方法中,我建议您在堆栈上创建对象: 像这样:

与使用堆相反:

 std::string* s = new std::string();
当对象超出范围时,在堆栈上创建的对象将被销毁。因此,不需要智能指针


您可以通过此链接了解更多信息:

一个
std::unique\u ptr
确保指向的对象不会被意外复制和正确删除。 由于您应该尽可能避免动态分配,因此只需将
std::string
保留为类的成员即可。如前所述,如果它是一个返回值,则string类足够聪明,能够以安全的方式正确移动资源。 您不需要保证字符串是唯一的,我的意思是,不存在副本,因此唯一ptr是一个太强的约束。
KIS规则:保持简单。

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

  • 使用
    std::string
    ,您无法控制如何、何时以及由谁分配缓冲区。虽然如果您使用不同的分配器(
    std::basic_string
    ),这种情况会有所缓解,但生成的类不是
    std::string
    ;并且通常不会被采用
    std::string
    的函数所接受。仅仅为了这个目的进入分配器可能没有意义
  • 更具体地说,您可以允许创建唯一的基于指针的字符串类作为现有缓冲区的所有者包装
  • 现在我们可以使用了,甚至在C++20的标准中(
    std::string_view
    ),您不必为唯一的基于指针的字符串重写整个字符串类;您只需在其上创建一个字符串视图,使用原始指针和以字节为单位的大小(如果您希望更好的空终止安全性,则使用大小-1)。如果您仍然需要std::string方法,则它们将是一行程序,例如。
    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); 
    }
    
  • 如果要在保持字符串大小的同时就地更新字符串,则
    std::string
    对您不起作用:它的大小和内容要么是完全恒定的,要么是可变的

为什么?为什么你需要一个指向
std::string
的指针?不,
std::string
本身就足够聪明了。这些答案值得一读:为什么人们投票关闭它是因为“不清楚你在问什么”?这个问题有什么不清楚的地方?在使用
unique\u ptr
的相同情况下,您会使用
unique\u ptr
。我无法想象这样的情况。。。但是如果出现了正确的情况,那么
unique\u ptr
将比
string*
原始指针要好得多。除非指针表示传递给函数的非拥有指针,并且可能为空。@MartinBonner:有C++17
std::optional
,对于没有C++17的人,请参阅Boost。但我忽略了这一点,因为它几乎肯定不需要。几乎没有任何情况需要区分空字符串和无字符串。啊,是的。在
std::string
的特定情况下,需要区分空和不存在是相当深奥的。我考虑的是更一般的情况,但关于所有权有一个普遍的原则。智能指针只能更好地拥有资源。他们并不擅长管理他们不拥有的资源。因此,智能指针不能与原始指针互换,因此一个指针优于另一个指针。它们只是用于不同的目的。@MSalters我的主要观点是,它不是智能指针和原始指针之间的“非此即彼”。在某些情况下,每种方法都是最好的。如果你告诉人们总是使用智能指针,他们会尝试使用
unique\u ptr
,而在不起作用的地方,他们会使用
shared\u ptr
。这不是好的做法。>std::string对象自己管理字符串的生命周期。这个信息真的很有用,而且我认为
std::string
是一个类。谢谢字符串对象不管理生命周期。它管理资源。字符串对象的生存期由语言管理。C++标准也没有提到“堆栈”这个词,就像你使用它一样。您将实现细节与更广泛的概念混淆:具有自动存储持续时间的对象@AkiraKido:
std::string
是一个类(好吧,是具体类模板实例化的别名)。“我不知道,为什么会有不同,尽管如此。”我非常感谢。我明白你的意思。然而,我没有混淆任何东西。我理解这个问题,这是最简单的解释方法。你可以看到这个链接:有一些简单的方法来制定概念,而不是
  std::string s;
 std::string* s = new std::string();
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); 
}