char* name = "name" 应该是无效的,但可以在大多数系统上编译,以便向后兼容没有 const 的旧时代,并且如果不编译它会破坏大量遗留代码。但它通常会收到警告。
危险在于你得到一个指向可写数据的指针(根据 C++ 规则可写),但如果你真的尝试写入它,你会调用 Undefined Behaviour,并且语言规则应该尽量保护你免受这种情况的影响尽可能合理。
正确的结构是
const char * name = "name";
上面没有错,即使在 C++ 中也是如此。使用字符串并不总是更正确。
你的第二个陈述应该是
std::string name = "name";
string 是标准库中定义的类(实际上是basic_string<char,char_traits<char>,allocator<char> 的 typedef),因此在命名空间 std 中(basic_string、char_traits 和分配器也是如此)
在各种情况下,使用字符串比使用 char 数组更可取。例如,在您的直接情况下,您可以修改它。所以
name[0] = 'N';
(将第一个字母转换为大写)对字符串有效,对 char*(未定义行为)或 const char *(不会编译)无效。如果你有char name[] = "name";
,你将被允许修改字符串
但是,如果想要将一个字符附加到字符串,std::string 构造是唯一可以让您干净地执行此操作的构造。使用旧的 C API,您必须使用 strcat(),但除非您分配了足够的内存来执行此操作,否则这将无效。
std::string 为您管理内存,因此您不必调用 malloc() 等。实际上分配器,第三个模板参数,管理下面的内存 - basic_string 请求它需要多少内存,但被解耦来自实际使用的内存分配技术,因此即使使用 std::string,您也可以使用内存池等来提高效率。
此外,basic_string 实际上并不执行许多字符串操作,而是通过 char_traits 完成的。 (这允许它使用经过优化的专业 C 函数)。
因此,当您处理在运行时构造和传递的动态字符串(而不仅仅是文字)时,
std::string 是管理字符串的最佳方式。
您很少会使用字符串*(指向字符串的指针)。如果你这样做,它将是一个指向对象的指针,就像任何其他指针一样。您将无法按照您的方式分配它。