Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我应该返回std::strings吗?_C++_String_Return Value - Fatal编程技术网

C++ 我应该返回std::strings吗?

C++ 我应该返回std::strings吗?,c++,string,return-value,C++,String,Return Value,我试图尽可能使用std::string而不是char*,但我担心可能会严重降低性能。这是返回字符串的一种好方法(不检查简短性的错误)吗 还有一个相关的问题:当接受字符串作为参数时,我应该将它们作为const std::string&或const char*接收吗 谢谢。返回字符串 我认为更好的抽象是值得的。在你能够测量出有意义的性能差异之前,我认为这是一个只存在于你想象中的微观优化 用了很多年才得到了一个好的C++抽象字符串。我不相信比亚恩·斯特劳斯特鲁(Bjarne Stroustroup)会

我试图尽可能使用
std::string
而不是
char*
,但我担心可能会严重降低性能。这是返回字符串的一种好方法(不检查简短性的错误)吗

还有一个相关的问题:当接受字符串作为参数时,我应该将它们作为
const std::string&
const char*
接收吗

谢谢。

返回字符串

我认为更好的抽象是值得的。在你能够测量出有意义的性能差异之前,我认为这是一个只存在于你想象中的微观优化


用了很多年才得到了一个好的C++抽象字符串。我不相信比亚恩·斯特劳斯特鲁(Bjarne Stroustroup)会允许一个明显的性能杀手出现在语言中,他以保守的“只为你使用的东西付费”格言而闻名。更高的抽象度是好的。

似乎是个好主意

如果这不是一个实时软件(比如游戏)的一部分,而是一个常规的应用程序,那么你应该很好


记住,“

我同意达菲莫的观点。您应该首先创建一个可理解的工作应用程序,然后,如果需要,进行攻击优化。正是在这一点上,你将知道主要的瓶颈在哪里,并将能够更有效地管理你的时间来制作更快的应用程序。

我同意@duffymo的观点。在进行测量之前不要进行优化,在进行微优化时,这是双重事实。始终:在优化前测量在优化后测量,看看您是否真的将事情做得更好。

在您的情况下,将进行返回值优化,因此不会复制std::string。

返回字符串,就表现而言,这并不是一个很大的损失,但它肯定会让你以后的工作变得轻松


另外,您可以始终内联函数,但大多数优化器无论如何都会修复它。

当您跨越模块边界时要小心


<> P>最好返回原始类型,因为C++类型不一定是二进制的兼容,即使是同一个编译器的不同版本。

< P>我同意其他的海报,你应该使用String。 但是要知道,根据编译器优化临时变量的力度,您可能会有一些额外的开销(超过使用动态字符数组)。(注意:好消息是,在C++0a中,明智地使用右值引用不需要通过编译器优化来提高效率——程序员将能够在不依赖编译器质量的情况下对其代码做出一些额外的性能保证。)

在您的情况下,额外的开销是否值得引入手动内存管理?大多数通情达理的程序员都会不同意——但如果你的应用程序最终出现性能问题,下一步将是分析你的应用程序——因此,如果你引入了复杂性,你只有在有充分证据表明需要提高整体效率时才会这样做

有人提到返回值优化(RVO)与此无关——我不同意

上面的标准文本(C++03)为(12.2):

[开始标准报价]

类类型的临时变量是在各种上下文中创建的:将右值绑定到引用(8.5.3)、返回右值(6.6.3)、创建右值的转换(4.1、5.2.9、5.2.11、5.4)、引发异常(15.1)、输入处理程序(15.3)以及某些初始化(8.5)。[注意:异常对象的生存期在15.1中描述。]即使避免创建临时对象(12.8),所有 必须像创建临时对象一样遵守限制。[示例:即使未调用复制构造函数,也应满足所有语义限制,如可访问性(第11条)。]

[示例: 结构X{ X(int); X(常数X&); ~X(); }; xf(X); void g() { xa(1); xb=f(X(2)); a=f(a); } 在这里,一个实现可以使用一个临时变量来构造X(2),然后使用X的复制构造函数将其传递给f();或者,可以在用于保存参数的空间中构造X(2)。此外,在使用X的复制构造函数将f(X(2))的结果复制到b之前,也可以使用临时变量来保存f(X(2));或者,f()的结果可能在b中构造。另一方面,表达式a=f(a)要求参数a或f(a)的结果具有临时性,以避免不希望的 a、 ]

[结束标准报价]

从本质上讲,上面的文字说明,您可以在初始化情况下依赖RVO,但在分配情况下不依赖RVO。原因是,当您初始化一个对象时,您所初始化的对象不可能被别名化到对象本身(这就是为什么您从不在复制构造函数中进行自检),但是当您执行赋值时,它可能会被别名化


您的代码本身并不禁止RVO,但请阅读您的编译器文档,以确保您确实需要它时可以真正依赖它。

返回字符串,就像大家说的那样

当接受字符串作为参数时,我应该以
const std::string&
const char*
的形式接收它们吗

我建议通过引用获取任何常量参数,除非它们足够轻量级,可以通过值获取,或者在少数情况下,需要空指针作为有效的输入,表示“以上都没有”。此策略不特定于字符串

非常量引用参数是有争议的,因为从调用代码(没有好的IDE)中,您无法立即看到它们是通过值还是通过引用传递的,而且差异很重要。因此,代码可能不清楚。对于常量参数,这不适用。阅读调用代码的人通常会认为这不是他们的问题,所以他们只是偶尔需要检查一下
std::string linux_settings_provider::get_home_folder() {
    return std::string(getenv("HOME"));
}
[Example: struct X { X(int); X(const X&); ˜X(); }; X f(X); void g() { X a(1); X b = f(X(2)); a = f(a); }