现在,这是高度概念性的。我不知道我是否正确理解了这一点,所以请帮助我理解其中的区别。
让我们假设name是一个私有的std::string数据成员,它由getName()访问器函数访问:
const string& getName() const {
return name;
}现在,这将返回一个对name的引用,这只是别名的另一个单词。因此,将返回别名,即返回name数据成员。这是允许的吗?它会违背数据隐藏的全部目的吗?
换句话说,上述方法与传统方法到底有什么不同:
string getName() const {
return name;
}???
最后,实现前者而不是后者真的值得吗?
发布于 2015-02-11 10:17:29
首先,如果基础值可能发生变化,尤其是在多线程执行的上下文中,那么引用确实会有问题。因此,这几乎是一个基本的假设,即数据成员的值在对象的生命周期内不会更改。它实际上是一个常数。
现在,引用的一个主要问题是它暴露了实现细节,因此很难更改实现。
一个更具学术色彩的问题是,如果之前存在按值返回,或者只是因为它不寻常,它可能会破坏代码。例如。
const string s& = foo().name();由于foo()通过值返回对象,而name()通过引用返回字符串,这为您提供了一个悬空的引用,而不是天真地预期的延长的生命周期。我称它为学术,因为我无法想象有人会写出这样的东西。尽管如此,墨菲定律和所有这些。
它可能不会(显著地)比值返回更有效,因为它不太可能仅仅用于初始化引用。
所以:
总而言之,就是不要。
这是过早的优化和复杂化。
发布于 2015-02-11 10:10:29
第一个允许调用者直接访问你的内部名称变量。假设它是常量,所以他们只能对它调用const方法。但您仍然希望外部调用者对您隐藏的内部数据进行操作吗?更糟糕的是,如果某个笨蛋决定const_cast字符串的内部数据缓冲区并破解它,该怎么办?
第二个函数返回一个内部name变量的副本。对任何调用者来说都是非常安全的。
我通常避开第一种类型,除非是琐碎的、低级的类型。但是不管怎样,琐碎的低级类型没有太多的复制开销。所以这意味着我从来没有写过这样的东西。
发布于 2015-02-11 10:06:47
常量引用返回更好,因为它不会复制字符串。我这么说的原因是因为这样的接口更灵活-如果需要的话,你总是可以将const引用复制到另一个字符串中,或者你可以将它作为一个引用-直到调用者。通过值返回一个成员,你总是被困在制作副本上。如果name很大或经常使用,那么它会影响性能,我认为性能是您使用C++的首要原因之一。
现在,其他答案提出了一些关于返回常量引用的负面观点,我认为这是无效的。
可以丢弃const的担忧是合理的,但丢弃const只是C++开发人员工具箱中的工具之一。为什么要把它拿走呢?如果有人真的想扰乱你的对象,他们总是可以在c++中通过直接寻址内存来做到这一点,所以设计你的代码来使你的调用者免于被调用是毫无意义的。抛弃const表明了这样做的意图,在我看来,这是完全可以的。这意味着调用者有一些非常具体的原因这样做,并且知道被抛出的const是针对非常数对象的,因此是安全的。
另一个答案中的学术例子太愚蠢了:
const string s& = foo().name();同样,将代码设计为试图将调用者从自身中拯救出来,这将限制您使用C++的能力。如果真的想做上面的事情,正确的方法应该是
string s = foo().name();因此,这一点也没有意义。
唯一有效的一点是,它在某种程度上公开了实现。然而,在我看来,效率的提高超过了这种担忧。
您真正应该问自己的是,使用name()的常见情况是什么?
通过回答这个问题,你将回答你应该使用哪种口味。
对我来说,它被称为name的事实意味着它将主要用于打印/日志记录和比较。因此,const引用显然是这里的赢家。
另外,看看外面的风格指南。它们中的大多数都会让你通过常量引用传递,并通过常量引用返回成员。如上所述,有很好的理由这样做。
https://stackoverflow.com/questions/28445353
复制相似问题