我从一开始就在学习C++,我不了解整个字符串主题。
以下三种代码之间有什么区别?
std::string s = std::string("foo"); std::string s = new std::string("foo"); std::string s = "foo";发布于 2011-11-09 17:37:15
std::string s = std::string("foo");这将创建一个包含"foo“的临时std::string对象,然后将其分配给s。(请注意,编译器可能会删除临时的。在这种情况下,临时elison是C++标准显式允许的。)
std::string s = new std::string("foo");这是一个编译器错误。表达式new std::string("foo")在空闲存储上创建一个std::string,并返回指向std::string的指针。然后尝试将std::string*类型的返回指针分配给类型为std::string的s。std::string类的设计防止了这种情况的发生,因此编译失败。
C++不是Java。通常不是这样创建对象的,因为如果忘记delete返回的std::string对象,就会泄漏内存。使用std::string的主要好处之一是它自动地为您管理底层字符串缓冲区,因此new-ing在某种程度上违背了这个目的。
std::string s = "foo";从技术上来说,它初始化了一个包含"foo“的新临时字符串,然后将其分配给s。同样,编译器通常会删除临时的(事实上,现在几乎所有非愚蠢的编译器实际上都消除了临时的),因此在实践中,它只是简单地构造了一个名为s的新对象。
具体来说,它调用std::string中接受const char*参数的转换构造函数。在上面的代码中,转换构造函数必须是非explicit的,否则就是编译器错误。实际上,转换构造函数是std::string的非std::string构造函数,所以上面的构造函数是编译的。
这就是通常初始化std::string的方式。当s超出作用域时,s对象将与底层字符串缓冲区一起被销毁。请注意,以下内容具有相同的效果(并且是初始化std::strings的另一种典型方式),因为它还生成一个名为s的对象,其中包含"foo“。
std::string s("foo");但是,there's a subtle difference between std::string s = "foo"; and std::string s("foo");,其中之一是在上述情况下转换构造函数可以是explicit或非explicit。
发布于 2011-11-09 17:43:59
std::string s = std::string("foo");这称为复制初始化。它在功能上与直接初始化相同。
std::string s( "foo" );但是,前者确实要求复制构造函数是可用的,编译器可以创建一个临时对象,但大多数编译器将删除临时构造器并直接构造s以包含"foo"。
std::string s = new std::string("foo");这将不会编译,因为new返回一个指针。要使它正常工作,您需要s的类型才能成为std::string *。然后,行动态地分配一个std::string对象并将指针存储在s中。一旦您使用完它,您就需要delete它。
std::string s = "foo";这几乎和第一次一样。它是复制初始化,但它有一个附加的约束。它要求std::string类包含一个接受const char *的非explicit构造函数。这允许编译器隐式地构造临时std::string对象。之后,语义与案例1完全相同。
发布于 2011-11-09 17:37:38
s
new std::string("foo")返回指向新分配内存的指针。为此,您应该将s声明为指向字符串std::string* s.中的字符串。
在大多数情况下--如果不是全部--你应该使用第三种选择。
https://stackoverflow.com/questions/8069092
复制相似问题