c++ - c语言返回字符串数组 - c输出字符串



在C++中返回字符串的最佳方式是什么? (5)

我的问题很简单:如果我有一个班级人,我想定义返回人名的成员函数,我更喜欢以下哪两种变体?

第一:

string name();

第二:

void name(/* OUT */ string &name);

第一种变体是低效的,因为它会产生不必要的拷贝(局部变量 - >返回值 - >赋值左边的变量)。

第二个变体看起来非常有效,但是这让我哭了

string name;
john.name(name);

而不是简单

string name(john.name());

那么,我更喜欢什么样的变体,以及效率和便利性/可读性之间的恰当折衷?

提前致谢。

https://src-bin.com


Answer #1

优化规则#1: 测量 ,优化,测量。 或者,正如Knuth所说,“不成熟的优化是一切罪恶的根源”。

除非你有强烈的表示,简单地返回std::string会显着影响你的软件的性能,只要这样做。 如果您可以衡量重大影响,找到关键路径并优化。 不要做任何有趣的项目范围的“优化”,这可能会导致很少或没有性能优势,但会对代码的可读性,可维护性和健壮性产生负面影响。


Answer #2

使用第一个变体:

string name();

编译器很可能会优化任何不必要的副本。 请参阅返回值优化

在C ++ 11中,移动语义意味着即使编译器不执行RVO,也不会执行完整的副本。 请参阅移动语义

另外请记住,如果替代方案是

void name(std::string& s);

那么你必须非常清楚地指定s可能发生什么以及它传递给函数时可能具有的值,并且可能执行很多有效性检查,或者完全覆盖输入。


Answer #3

我认为你应该使用第一个变体。 因为这是简单的getter方法,并且这种getter / setter方法在任何地方都可以使用。


Answer #4

既然你想为你的类的字段创建一个getter,也许你应该这样做: inline const std::string& name() const { return this->name; } inline const std::string& name() const { return this->name; }

由于该名称是作为const引用返回的,因此它不会在类外部修改,也不会通过返回名称来创建副本。

之后,如果你想操纵名字,你将不得不做一个副本。


Answer #5

这是一个很好的问题,而且你问的事实表明你正在关注你的代码。 然而,好消息是,在这种特殊情况下,有一个简单的方法。

首先,干净的方法是正确的做法。 在大多数情况下, 编译器会消除不必要的副本 (通常在有意义的地方)。

编辑(6/25/2016)

不幸的是,David Abaraham的网站似乎已经脱机了几年,而且这篇文章已经被ethers(没有archive.org副本)所遗失。 为了存档目的,我已经自由地将本地副本上传为PDF, 可以在此处找到它。





string