C++ ';常量字符串&;getName()常量{}';vs';字符串getName()常量{}';?
现在,这是高度概念化的。我不知道我是否理解正确,所以请帮助我理解其中的区别 让我们假设C++ ';常量字符串&;getName()常量{}';vs';字符串getName()常量{}';?,c++,C++,现在,这是高度概念化的。我不知道我是否理解正确,所以请帮助我理解其中的区别 让我们假设name是一个私有std::string数据成员,由getName()访问器函数访问: const string& getName() const { return name; } 现在,这将返回一个引用,它只是别名的另一个单词,指向name。因此,将返回一个别名,即返回名称数据成员。这是允许的还是会破坏数据隐藏的全部目的 换言之,上述方法与传统方法究竟有何区别: string ge
name
是一个私有std::string
数据成员,由getName()
访问器函数访问:
const string& getName() const {
return name;
}
现在,这将返回一个引用,它只是别名的另一个单词,指向name
。因此,将返回一个别名,即返回名称
数据成员。这是允许的还是会破坏数据隐藏的全部目的
换言之,上述方法与传统方法究竟有何区别:
string getName() const {
return name;
}
最后,实现前者而不是后者真的值得吗?常量引用返回更好,因为它不复制字符串。我之所以这样说,是因为接口以这种方式更加灵活-如果需要,您可以随时将const引用复制到另一个字符串中,或者您可以将其用作引用-直到调用方。按值返回成员时,您总是要复制副本。如果
你可以抛弃这个常量,这是有效的,但是抛弃const只是C++开发者工具箱中的工具之一。为什么要把它拿走?如果有人真的想和你的对象乱搞,他们可以直接在C++中通过直接处理内存来完成,所以设计你的代码来保存你的呼叫者是没有意义的。扔掉const显示了这样做的意图,在我看来是完全可以的。这意味着调用方有一些非常具体的原因这样做,并且知道被丢弃的常量是用于非常量对象的,因此是安全的
另一个答案中的学术例子很愚蠢:const string s& = foo().name();
再次,设计代码试图从自己保存呼叫者,这限制了C++的能力。如果一个人真的想做上述事情,正确的方法是
string s = foo().name();
所以这一点也没有意义
唯一有效的一点是,它在某种程度上公开了实现。然而,在我看来,效率的提高超过了这一担忧
您真正应该问自己的是,使用name()
的通常情况是什么
通过回答这个问题,你将回答你应该使用哪种口味
对我来说,它被称为name
意味着它主要用于打印/记录和比较。因此,const引用显然是这里的赢家
另外,请看外面的样式指南。它们中的大多数将让您通过常量引用传递,并通过常量引用返回成员。如上所述,这样做有很好的理由。第一种方法允许调用者直接访问您的内部名称变量。假设它是常量,所以他们只能对它调用const方法。但您仍然希望外部调用者对隐藏的内部数据进行操作吗?更糟糕的是,如果某个bozo决定强制转换字符串的内部数据缓冲区并对其进行攻击,该怎么办 第二个返回内部名称变量的副本。对任何来电者来说都非常安全
我通常会避开第一种类型,除了琐碎的、低级的类型。但是,简单的低级类型无论如何都不会有太多的复制开销。这意味着我从来没有写过这样的东西 首先,如果基础值可能发生变化,那么引用确实会有问题,特别是在多线程执行的上下文中。因此,这几乎是一个基本假设,即数据成员的值在对象的生命周期内不会改变。它实际上是一个常数 现在,引用的一个主要问题是它暴露了实现细节,因此很难更改实现 一个更具学术性的问题是,如果之前有按值返回,或者仅仅因为它不寻常,它可能会破坏代码。例如
const string s& = foo().name();
使用foo()
通过值返回对象,以及name()
通过引用返回字符串,这将为您提供一个悬空引用,而不是天真地期望延长的生命周期。我称之为学术性的,因为我无法想象有人会这样写。不过,墨菲定律和所有这些
它可能不会(显著地)比值返回更有效,因为它不太可能仅用于初始化引用
因此:
- 可能效率不会明显提高
- 防止轻松更改实施
- 也有一个学术问题,产生悬而未决的参考文献
这是过早的优化和复杂化。不要这样做。你想说什么?一个是副本,一个是reference@JamesMoore:一个是副本,一个是引用的副本,怎么样?另一个需要考虑的问题是,首先你真的需要一个getter函数吗?“更好”这是一个观点问题,每个版本都有其优缺点。除了是否制作副本之外,还有其他考虑因素。这可能还取决于对象最常见的用例。@MattMcNabb。没错,我对我的答案进行了更好的解释……没有双关语;)它可能不会比值返回更有效,确切地说是b因为它不太可能仅仅用于初始化引用-我强烈反对这一点。它被称为
name
,这一事实意味着它很可能被用于比较、打印/记录、作为地图中的一个键等。这些用途中的大多数将更加有效。现在,你的学术示例只是在推动它……你所拥有的一切做我