问题描述
关于 const
引用(对 const 的引用)的现有问题很多。但是当存在隐式转换时,const
引用也会导致一个新地址。我在下面写了这个例子:
int i = 42;
double d = 4.2;
const int& ri1 = i;
const int& ri2 = d;
&ri1
和 &i
会打印相同的地址,但是 &ri2
和 &d
是不同的。 ri2
真正服务的对象是什么?正如“C++ Primer” 所说,它会生成一个临时对象。但是如果转换后的 const 引用使用了差异地址,那意味着这个地址仍然有一个有效的对象。
假设我有一个很长的 string
或 const char*
作为“长示例文本”,并将其传递给某个接受 const string&
的函数,会发生类似的转换。
解决方法
确实有一个未命名的 int
对象,其值为 4。这需要一些内存。
对于 std::string
示例,const string&
可以绑定到 string
参数而不会导致复制。但是 const char*
参数会导致复制。您可以考虑使用 std::string_view
。
这样想是有帮助的:
如果此绑定会导致此对象更改,我们不希望将 (plain) &
引用绑定到该对象。例如。从 3.1415 到 3,就像这里:
double pi = 3.1415;
int& r = pi; // Imagine,now both r and pi are 3...
我们不能将 r
的类型更改为 double
(否则,这对于语言来说将是一个相当大的逻辑!)。
而且我确信大多数 C++ 用户不希望将所引用的 pi
的值更改为 3(因为 r
是 int
),就像引用绑定的结果。
我们需要通过将 pi
转换为 r
的类型来创建一个新对象。当我们发生转换时,引用将绑定到作为此转换结果创建的临时对象。
我们没有其他(除了引用“句柄”) 访问权限的对这个未命名对象的非const
引用没有理由。如果我们出于某种原因想要更改它,我们可以将 pi
复制到 int i
并将 i
更改为我们想要的任何内容。
回答问题的关键点:
是的,如果 from const char*
to const string&
,它会产生额外的负担,但是这可能不是const string&
的预期用途。
为什么?因为如果你确定你的函数将被传递一个 const char*
(并且只有它)并且你负担不起任何开销,那么你为什么要声明一个像 const string&
这样的参数。 好吧,可能有几个正当的理由,所有这些理由都值得付出代价。
在其他情况下,当传递 string
时,您将避免复制。双赢,不是吗?