1
55
唯一可能导致问题的方法是调用方存储引用,而不是复制字符串,并在对象被破坏后尝试使用它。这样地:
但是,由于您的现有函数返回一个副本,所以您不会破坏任何现有代码。 |
2
28
实际上,另一个问题
明确地
返回字符串
不
参考一下,事实是
如果调用者要做这种事情,最好使用某种类型的智能指针或常量引用,或者至少在foo.name()方法上有一个讨厌的警告注释头。我提到JNI,因为以前的Java编码器可能特别容易受到这种类型的链接的伤害,而这种链接可能看起来无害。 |
3
17
常量引用返回的一个问题是,如果用户编写了如下代码:
用一个
但发生了什么
所以我倾向于使用const-reference返回(因为,无论如何,我更愿意发送引用,而不是希望编译器优化额外的临时引用),只要遵守下面的约定:“如果您希望它超出我的对象的存在范围,他们会在我的对象被破坏之前复制它。” |
4
10
std::string的一些实现与copy-on-write语义共享内存,因此按值返回的效率几乎与按引用返回的效率相同。 和 你不必担心终身问题(运行时为你做的)。 如果你担心表现,那么 基准IT (<=压力不够大)!!!!尝试两种方法并测量收益(或不足)。如果一个更好,你真的在乎,那就用它。如果没有,那么更喜欢按价值来保护它,因为它提供了其他人提到的终身问题。 你知道他们对假设的看法… |
5
7
好的,所以 差异 在返回副本和返回引用之间有:
如果你想要它
快速安全
使用
Boost::共享资源
. 对象可以在内部将字符串存储为
|
6
4
我会将其更改为返回const std::string&。如果您不更改所有调用代码,调用方可能会复制结果,但不会带来任何问题。 如果有多个线程调用name(),则会出现一个潜在的褶皱。如果返回一个引用,但稍后更改基础值,则调用方的值将更改。但是现有的代码看起来并不是线程安全的。 看看Dima对一个潜在但不太可能出现的问题的答案。 |
7
3
可以想象,如果调用者真的想要一个副本,你可以破坏一些东西,因为他们将要改变原始版本,并且想要保留一个副本。然而,更可能的是,它实际上应该返回一个常量引用。 最简单的方法是尝试它,然后测试它,看看它是否仍然有效,前提是您可以运行某种类型的测试。如果没有,在继续重构之前,我将集中精力首先编写测试。 |
8
2
重要吗?只要使用现代的优化编译器,按值返回的函数就不会涉及到副本,除非它们在语义上是必需的。 见 the C++ lite FAQ 对此。 |
9
1
如果更改为常量引用,该函数的典型用法将不会中断,这种可能性非常大。 如果调用该函数的所有代码都在您的控制之下,只需进行更改,看看编译器是否会抱怨。 |
10
0
取决于你需要做什么。也许您希望所有调用方在不更改类的情况下更改返回值。如果返回的常量引用不会飞。 当然,下一个论点是调用者可以自己制作副本。但是,如果您知道如何使用函数,并且知道无论如何都会发生这种情况,那么这样做可能会在代码中为您节省一步。 |
11
0
我通常返回const&除非不能返回。qbziz给出了一个示例,说明情况是什么。当然,qbziz还声称std::string具有copy-on-write语义,这在今天很少是真的,因为cow在多线程环境中涉及大量开销。通过返回const,您可以让调用者有义务在字符串结束时做正确的事情。但是,由于您处理的代码已经在使用中,所以您可能不应该更改它,除非分析显示复制此字符串会导致大量的性能问题。然后,如果你决定改变它,你需要仔细考虑,以确保你没有破坏任何东西。希望与您一起工作的其他开发人员不要做像dima答案中那样的粗略的事情。 |
12
0
返回对成员的引用将公开类的实现。 这可以防止改变班级。在需要优化的情况下,可能对私有或受保护的方法有用。 What should a C++ getter return |