【问题标题】:c++ when to return a const char* instead of a std:stringc++ 何时返回 const char* 而不是 std:string
【发布时间】:2018-10-04 11:52:12
【问题描述】:

在下面的课程中,speak() 返回 const char* 而不是 std::string 有什么好处或理由吗?

class Animal
{
protected:
    std::string m_name;

    Animal(std::string name)
    : m_name(name)
    {
    }

public:
    std::string getName() { return m_name; }
    const char* speak() { return "???"; }
};

【问题讨论】:

  • 当您返回指向字符串文字的指针时,它不会创建字符串的新副本。当您返回 std::string 时,它需要复制内存。
  • 一如既往:视情况而定
  • @PeterT 谢谢你,这是一个很好的答案。
  • 您需要const char*,例如,在与用 C 编写的库交互时。一个示例是通过 MPI 库发送字符串。
  • @Galik 通过 ref 返回在许多情况下是不合适的,而且非常危险。就我个人而言,我建议 OP 通过复制返回一个 std::string 。编译器优化很多。

标签: c++ string pointers char


【解决方案1】:

诸如"???" 之类的字符串文字的作用是告诉编译器包含一块包含特定字符序列的全局内存(加上末尾的字符'\0')。字符串文字表达式有一个类型为 const char* 的值,指向那块全局内存。

这意味着在这种非常特殊的情况中,传递指针是安全的。注意下面的函数

std::string speak() { return "???"; }

具有相同的函数体,但代码路径完全不同。字符串文字表达式(全局内存、指针)仍然存在,但它被用作std::string 的构造函数的参数;它被隐式转换为std::string

std::string 的构造函数动态分配一些内存(在这种情况下,可能不会使用短字符串优化)并从您给它的指针复制。

所以在这个非常特殊的情况下,如果你有一个字符串文字而没有别的,你可以返回一个const char*。当传递给另一个期望它的函数时,它可能会隐式转换为 std::string,因此 const char* 并不是什么优化。

【讨论】:

  • 从 C++17 开始有另一个选项,即返回 std::string_view。这也不会分配内存,还会提供编译时字符串的长度。这应该是首选变体,因为它还告诉调用者字符串有正确的绑定,普通的 char * 可能指向非零终止的内容或包含多个零字节的字符串。
【解决方案2】:

std::string 带有许多可能不需要和未使用的功能。如果您不想要所有这些功能,您应该考虑使用成本。传递std::string 至少需要从文字到字符串的内部存储的第一个副本。如果您将字符串传递给其他函数并返回,也许您会得到一些额外的副本。如果存在小字符串优化,您不能简单地移动字符串,因此在这种情况下成本会变得更高。

如果您不想要成本但获得常量字符串的所有功能,您应该查看std::string_view。该实现通常只包含一个指向底层数据的指针和一个大小值。所以它的成本更低,而且功能非常丰富。

如果符合您的需要,传递const char* 确实没有错。

对于常量字符串始终使用std::string 是一种非常常见的模式,但不是一个好的模式。

【讨论】:

    【解决方案3】:

    除了其他答案之外,如果您需要从用不同 C++ 编译器编写的不同库调用函数,则可能需要返回 const char*。例如,您的 Animal 类可能使用 Visual Studio 2013 编译,但您使用 Animal 类的库可能使用 Visual Studio 2015 编译。

    更多信息: How do I safely pass objects, especially STL objects, to and from a DLL?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多