C++字符串声明

Ori*_*ski 27 c++ string

我从一开始就学习C++而且我没有得到整个字符串主题.

以下三个代码有什么区别?

  1. std::string s = std::string("foo");
  2. std::string s = new std::string("foo");
  3. std::string s = "foo";

In *_*ico 42

std::string s = std::string("foo");
Run Code Online (Sandbox Code Playgroud)

这将创建一个std::string包含"foo" 的临时对象,然后将其分配给s.(请注意,编译器可能会忽略临时.在这种情况下,临时elison是C++标准明确允许的.)

std::string s = new std::string("foo");
Run Code Online (Sandbox Code Playgroud)

这是编译器错误.表达式在free store上new std::string("foo") 创建一个std::string并返回一个指针std::string.然后,它会尝试类型的返回指针赋值std::string*s类型std::string.std::string类的设计可以防止这种情况发生,因此编译失败.

C++不是Java.这不是通常创建对象的方式,因为如果忘记delete返回的std::string对象,则会泄漏内存.使用的一个主要好处std::string是它会自动为您管理底层字符串缓冲区,因此new它会破坏这一目的.

std::string s = "foo";
Run Code Online (Sandbox Code Playgroud)

这基本上与#1相同.它在技术上初始化一个新的临时字符串,它将包含"foo",然后分配给它s.同样,编译器通常会忽略临时(事实上,现在几乎所有非愚蠢的编译器实际上都消除了临时编译器),所以在实践中它只是构造一个s就地调用的新对象.

具体来说,它调用一个std::string接受const char*参数的转换构造函数.在上面的代码中,转换构造函数必须是非构造函数explicit,否则它是编译器错误.转换构造其实是在非explicitstd::stringS,SO上面并编译.

这是std::string通常初始化的方式.当s超出范围,该s对象将与下面的字符串缓冲区被破坏沿着.请注意,以下内容具有相同的效果(并且是另一种典型std::string的初始化方式),因为它还会生成一个名为s"foo" 的对象.

std::string s("foo");
Run Code Online (Sandbox Code Playgroud)

然而,std::string s = "foo";和之间存在细微的差别std::string s("foo");,其中之一是转换构造函数可以是上述情况中的任何一个explicit或不是explicit.

  • +1作为答案,提到编译器不一定在#1中创建临时. (3认同)