这是一个来自interiew的问题,以及下面的代码.这个功能有什么问题?
string f() {
return "hello world";
}
Run Code Online (Sandbox Code Playgroud)
对我来说,没有任何错误,我甚至可以使用此功能运行程序:
#include <iostream>
#include <string>
using namespace std;
string f() {
return "hello world";
}
int main() {
string s2=f();
cout<<s2<<endl;
}
Run Code Online (Sandbox Code Playgroud)
什么是错这个功能呢?
嗯......有一些安慰,在这类问题中,往往没有正确的答案.你可能希望最好的方法是通过展示你的专业知识来详细说明利弊(也就是代码手淫)来让面试官惊叹不已.
从样式的角度来看,使用按值返回返回对象往往很糟糕.考虑:
X f();
X x;
x = f();
Run Code Online (Sandbox Code Playgroud)
f分配一个X.需要返回一个X,因此在堆栈上放置一个额外的副本作为返回值.最后,堆栈上的x通过赋值运算符复制到x中.总共有3个X出现在内存中.有人可能会说这是低效的,因此当值是对象时,您应该尝试不按值返回.
然而,一位更精明的受访者可能会指出:
那么,还有什么选择?
X const& f();
Run Code Online (Sandbox Code Playgroud)
可以考虑作为替代方案.但是,这有其自己的样式问题,因为调用者不清楚结果的生命周期.也许下次调用会使之前的参考结果无效?谁知道?
也
void f_get( X& result );
Run Code Online (Sandbox Code Playgroud)
可能是首选(由一些采访者).这有以下好处:
在这两者中,牺牲了可读性 - 在一般情况下,调用者现在必须更加注意哪些参数是功能参数,哪些是用于保存结果.
在OP中,堆栈中字符串文字的生命周期也不是很明显.当函数返回时是否从堆栈中取消分配?可能不是 - 它可能保存在静态内存区域(最好检查规格是否确定).但如果没有,那么结果是什么 - 可能没有,因为字符串可能会在堆上创建char const*的副本,除非你有一些奇怪的字符串实现,他们的构造函数可以通过一些聪明的模板类型告诉区分文字和非文字参数 - 魔法.
在任何情况下,像这样喷射一些BS肯定会得分,如果没有标记.
你的控制台输出ascii,UTF-8还是unicode?这个程序可能对其中一个人来说是错误的,而且在没有说英语的地方也是错误的.
您是否检查过stdout是否具有有效值,或者您是否在Windows中没有-D_CONSOLE进行编译,或者某些嵌入式设备或游戏控制台中没有stdout,您必须重定向到日志库(或崩溃)?
嗯......接受你的选择.
临时副本可能是他们正在寻找的机器人.因为在一个字符串的情况下暂时没有任何后果(也可能是复制省略),面试官闻到了接骨木果子,而他的母亲是一只山羊