嗯……安慰一下,在这类问题中,通常没有正确答案。您可能希望的最好结果是通过展示您的专业知识来详细说明利弊(也称为代码手淫),从而让面试官惊叹。
从风格的角度来看,使用按值返回来返回对象通常是不好的。考虑:
X f();
X x;
x = f();
f 分配一个 X。需要返回一个 X,因此在堆栈上放置了一个额外的副本作为返回值。最后,堆栈上的 x 通过赋值运算符复制到 x 中。总共有 3 个 X 出现在内存中。有人可能会说这是低效的,所以当值是一个对象时,你应该尽量不要按值返回。
然而,更精明的受访者可能会指出:
- 一些编译器优化了临时副本。对于这种优化,我相信对 X 的赋值是通过复制构造函数还是相等运算符进行的。说“copy elison”,看看面试官是否扬眉:什么是copy elision,它是如何优化copy-and-swap 习语的?. 我猜复制省略可能在这里起作用,因为该函数位于同一个翻译单元中,因此很容易内联。
- 几乎所有字符串类的实现都实现了写入时复制,在这种情况下,字符串文本数据的单个副本将被保存,其余数据保存在堆栈中,并且在字符串被保存时基本上不会造成开销复制。
- 如果您使用的是早期版本的 Visual Studio,则会出现内存泄漏
那么,有什么替代方案呢?
X const& f();
可以考虑作为替代方案。但是,这有其自身的风格问题,因为调用者不清楚结果的生命周期。也许下一次调用会使先前的参考结果无效?谁知道?
还
void f_get( X& result );
可能是首选(一些面试官)。这有以下好处:
- 没有局部变量的副本
- 没有不确定生命周期的引用/指针
- 在 X 是字符串的情况下,只保存一个文本数据的副本(尽管在所有情况下都是如此)
在这两种情况下,都牺牲了可读性——在一般情况下,调用者现在必须更加注意哪些参数是函数参数,哪些是用来保存结果的。
在 OP 中,堆栈上字符串文字的生命周期可能也不明显。函数返回时是否从堆栈中取消分配?可能不是——它可能保存在静态内存区域中(最好检查规范以确保)。但如果不是,那么结果是什么 - 可能没有,因为字符串可能会在堆上复制 char const* ,除非你有一些奇怪的字符串实现,谁的构造函数可以用一些聪明的模板类型区分文字和非文字参数-特质魔法。
无论如何,像这样说一些废话肯定会得分,如果偏离标准的话。
另外,您的控制台输出的是 ascii、UTF-8 还是 unicode?该程序可能对其中一个错误,并且在没有说英语的语言环境中也是错误的。
您是否检查了标准输出是否具有有效值,或者您是否在 Windows 中没有 -D_CONSOLE 进行编译,或者对于标准输出不可用且您必须重定向到日志库(或崩溃)的某些嵌入式设备或游戏控制台?
嗯……随便挑吧。
临时副本可能是他们正在寻找的机器人。因为在字符串的情况下临时是没有意义的(可能还有复制省略),面试官闻起来有接骨木浆果的味道,他的母亲是山羊