C++ 字符串声明
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8069092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ string declaration
提问by Ori Popowski
I am learning C++ from the beginning and I don't get the whole strings topic.
我从一开始就在学习 C++,但我没有了解整个字符串主题。
What is the difference between the following three codes?
下面三个代码有什么区别?
std::string s = std::string("foo");
std::string s = new std::string("foo");
std::string s = "foo";
std::string s = std::string("foo");
std::string s = new std::string("foo");
std::string s = "foo";
回答by In silico
std::string s = std::string("foo");
This creates a temporary std::string
object containing "foo", then assigns it to s
. (Note that compilers may elide the temporary. The temporary elison in this case is explicitly allowed by the C++ standard.)
这将创建一个std::string
包含“foo”的临时对象,然后将其分配给s
. (请注意,编译器可能会省略临时的。在这种情况下,临时 elison 是 C++ 标准明确允许的。)
std::string s = new std::string("foo");
This is a compiler error. The expression new std::string("foo")
creates an std::string
on the free storeand returns a pointer to an std::string
. It then attempts to assign the returned pointer of type std::string*
to s
of type std::string
. The design of the std::string
class prevents that from happening, so the compile fails.
这是一个编译器错误。该表达式在空闲存储上new std::string("foo")
创建 anstd::string
并返回一个指向 an 的指针std::string
。然后它尝试将返回的 type 指针分配std::string*
给s
of type std::string
。std::string
类的设计防止这种情况发生,因此编译失败。
C++ is not Java. This is not how objects are typically created, because if you forget to delete
the returned std::string
object you will leak memory. One of the main benefits of using std::string
is that it manages the underlying string buffer for you automatically, so new
-ing it kind of defeats that purpose.
C++ 不是 Java。这不是通常创建对象的方式,因为如果您忘记delete
返回的std::string
对象,您将泄漏内存。使用的主要好处之一std::string
是它自动为您管理底层字符串缓冲区,因此 - new
ing 它有点违背了这个目的。
std::string s = "foo";
This is essentially the same as #1. It technically initializes a new temporary string which will contain "foo", then assigns it to s
. Again, compilers will typically elide the temporary (and in fact pretty much all non-stupid compilers nowadays do in fact eliminate the temporary), so in practice it simply constructs a new object called s
in place.
这与#1 基本相同。从技术上讲,它会初始化一个新的临时字符串,该字符串将包含“foo”,然后将其分配给s
. 同样,编译器通常会删除临时对象(事实上,现在几乎所有非愚蠢的编译器都确实删除了临时对象),因此在实践中它只是构造一个新对象s
就地调用。
Specifically it invokes a converting constructor in std::string
that accepts a const char*
argument. In the above code, the converting constructor is required to be non-explicit
, otherwise it's a compiler error. The converting constructor is in fact non-explicit
for std::string
s, so the above does compile.
具体来说,它调用一个std::string
接受const char*
参数的转换构造函数。上面代码中,转换构造函数必须是 non- explicit
,否则是编译器错误。转换构造函数实际上是非explicit
for std::string
s,所以上面的确实可以编译。
This is how std::string
s are typically initialized. When s
goes out of scope, the s
object will be destroyed along with the underlying string buffer. Note that the following has the same effect (and is another typical way std::string
s are initialized), in the sense that it also produces an object called s
containing "foo".
这就是std::string
s 通常的初始化方式。当s
超出范围时,s
对象将与底层字符串缓冲区一起销毁。请注意,以下具有相同的效果(并且是std::string
s 的另一种典型初始化方式),因为它也生成了一个名为s
“foo”的对象。
std::string s("foo");
However, there's a subtle difference between std::string s = "foo";
and std::string s("foo");
, one of them being that the converting constructor can be either explicit
or non-explicit
in the above case.
但是,and之间存在细微差别std::string s = "foo";
std::string s("foo");
,其中之一是转换构造函数在上述情况下可以是explicit
或非explicit
。
回答by Praetorian
std::string s = std::string("foo");
This is called copy initialization. It is functionally the same as direct initialization
这称为复制初始化。它在功能上与直接初始化相同
std::string s( "foo" );
but the former does require that the copy constructor is available and compilers may create a temporary object but most will elide the temporary and directly construct s
to contain "foo"
.
但前者确实需要复制构造函数可用,编译器可以创建一个临时对象,但大多数会省略临时和直接构造s
以包含"foo"
.
std::string s = new std::string("foo");
This will not compile because new
returns a pointer. To make it work you'd need the type of s
to be a std::string *
. Then the line dynamically allocates an std::string
object and stores the pointer in s
. You'll need to delete
it once you're done using it.
这不会编译,因为new
返回一个指针。为了让它工作,你需要的类型s
是std::string *
. 然后该行动态分配一个std::string
对象并将指针存储在s
. delete
一旦你用完它,你就需要它。
std::string s = "foo";
This is almost the same as first. It is copy initialization but it has an added constraint. It requires that the std::string
class contains a non-explicit
constructor that takes a const char *
. This allows the compiler to implicitly construct a temporary std::string
object. After that the semantics are identical to case 1.
这与第一次几乎相同。它是复制初始化,但它有一个附加的约束。它要求std::string
该类包含一个explicit
采用const char *
. 这允许编译器隐式构造一个临时std::string
对象。之后的语义与情况 1 相同。
回答by Kleist
- Creates a temporary string object and copies the value to
s
- Does not compile,
new std::string("foo")
returns a pointer to some newly allocated memory. For this to work, you should declare s as a pointer to a stringstd::string* s
. - Constructs a string from a C-string.
- 创建一个临时字符串对象并将值复制到
s
- 不编译,
new std::string("foo")
返回指向一些新分配内存的指针。为此,您应该将 s 声明为指向 string 的指针std::string* s
。 - 从 C 字符串构造一个字符串。
You should use the third option in most - if not all - cases.
在大多数(如果不是全部)情况下,您应该使用第三个选项。
回答by Fred
1 will create a temporary variable (right hand side), then call the assignment operator to assign the value to s
1 将创建一个临时变量(右侧),然后调用赋值运算符将值赋值给 s
2 will create an instance of std::string
on the heap and return a pointer to it, and will fail in the assignment because you can't assign a pointer to a non-pointer type
2 将std::string
在堆上创建一个实例并返回一个指向它的指针,并且会在赋值中失败,因为您不能将指针分配给非指针类型
3 will build a std::string and initialize it from a const char*
3 将构建一个 std::string 并从一个 const char*
回答by seth
On the number 1, you are creating a temporary string using the constructor and then assigning it to s. Number 2 doesn't even compile. On number 3, you are creating a new string and then assign a value to it.
在数字 1 上,您正在使用构造函数创建一个临时字符串,然后将其分配给 s。2号甚至不编译。在数字 3 上,您正在创建一个新字符串,然后为其分配一个值。