【问题标题】:Pointer to reference引用指针
【发布时间】:2016-06-09 09:48:19
【问题描述】:

我在看,看到如下代码:

template <>
inline bool is_empty(const char* const& x)
{
    return x==0 || *x==0;
}

const char* const&amp; x 是什么意思?

我尝试了以下代码来理解它:

void f(const char* const& x) 
{
    // whatever
}

void main()
{
    char a = 'z';
    char &j = a;
    f(a);//error
    f(*a);//error
    f(&a);//fine
    f(j);//error
    f(&j);//fine     
    f('z');//error
}

它仅适用于f(&amp;a) 和f(&amp;j)。

const char* const&amp; x 究竟是什么意思?

【问题讨论】:

  • 就像f(const T&amp;),其中T = const char*。
  • const 限定了一个类型,使得修改对象变得不合时宜。您在每种情况下收到的错误消息都应该解释发生了什么。
  • 请注意,它不是标题所说的引用指针(不存在这样的东西),而是对指针的引用。
  • 我本来想说按引用传递似乎没用,但它看起来像是模板专业化,模板在一般情况下接受引用。
  • 经验法则:从右到左阅读类型声明。所以“const char* const& x”的意思是“x 是对常量(第二个常量)指针(*)的引用(&),指向一个常量(第一个常量)的字符”。 -- 顺便说一句,这就是为什么我更喜欢等效的“char const * const & x”(x 是对指向常量 char 的常量指针的引用)。或类型定义。 typedef 是你的朋友。

标签: c++


【解决方案1】:

cdecl 是一个有用的在线工具,可以帮助初学者习惯复杂的声明。

插入const char* const&amp; i 返回:

将 i 声明为指向 const char 的 const 指针的引用

现在声明的意思应该很明显了。

【讨论】:

  • 我认为它是“对 char 类型常量指针的常量引用”
  • @sagar:不,没有常量引用这样的东西。本质上,引用本身是恒定的(不能重新定位),因此在它之前添加“恒定”是一个 pleonasm。
  • @MarcvanLeeuwen 是的,你在写。我误解了声明。谢谢你的澄清。
  • @MarcvanLeeuwen 是的。常量引用与常量引用是一回事。虽然,既然是同一个东西,萨格尔的“修正”就有点多余了。常量(或 const)引用在特定情况下(根据我的经验)比对 const 的引用更多,尽管后者更具描述性,因此在这种情况下更好,因为清晰很重要。
  • @sagar ...虽然,将常量添加到“对 const 的引用”确实是多余的,而且它确实是指向 const char 的指针,所以我并不是说被误解的声明是正确的。
【解决方案2】:

让我们把它拆开:

  • 结尾的&amp; 表示这是对任何类型的引用。

  • const char 是被指向的类型

  • * const表示指针不变

所以,这是对指向 const char 的 const 指针的引用。你不能改变它指向的char(除非你抛弃constness),你也不能改变指针(即让它指向别的东西)。指针通过引用传递,因此不会发生复制。

【讨论】:

  • 这意味着什么?
  • 简单明了。并且使用 'const &' 模式使得f("hello"); 也可以接受。
【解决方案3】:

指针引用正是它所说的,对指针的引用。

考虑一下我们对引用的了解。 C++ 中的引用是指在别处引用现有变量的变量:

int x = 1;
int &y = x;    // <-- y refers to x. Any changes to y will update x as well, and vice versa.

还要考虑一下我们对指针的了解。一个指针指向内存中的另一个对象:

int *m = new int(5);   // Pointer to an allocated integer in memory.
int *n = m;            // Pointer to the same memory.

因此,在您的情况下,您实际上拥有的是对指针的引用!

int *m = new int(5);   // Pointer to an allocated integer in memory.
int *ptr = m;          // Pointer to m.
int *&ptrRef = ptr;    // Reference to ptr.

在上面的示例中,更改 ptrRef 会更新 指针,但不会更新值。

这里有一个完整的例子:

int *myPtr = new int(5);   // myPtr points to an integer.

...

void ChangePointer(int *&ptr)
{
    delete ptr;
    ptr = new int(6);
}

...

std::cout << *myPtr << std::endl;  // <-- Output "5"
ChangePointer(myPtr);
std::cout << *myPtr << std::endl;  // <-- Output "6"

在上面的示例中,我们通过引用将myPtr 传递给ChangePointer,以便函数可以对其进行修改。如果我们不通过引用传递,则函数内部所做的任何更改都将丢失。

在您的情况下,您传递的是对 const 指针的引用。这大约相当于:

DoStuff(const Object &myObject);

在你的情况下,你传递的是一个指针,而不是一个对象。

虽然通过引用传递 const 指针似乎有点多余。指针不能更改(它是 const),并且通过引用传递指针没有任何好处(对于像指针和整数这样的小对象,通过引用传递并不比通过值传递更有效)。我不想猜测为什么会在你的情况下这样做。

【讨论】:

  • 你能修复第一个代码段中的第 2 行吗?您使用“a”而不是“x”。这有点令人困惑。
【解决方案4】:

其他答案主要涵盖指针引用的语义。

但如果您有疑问:它是 对指针的引用还是对引用的指针?这可能会令人困惑!但是,C++ 不允许指向引用的指针!

指针存放的是对象的地址,引用是不是对象,所以不能有任何指针指向。

【讨论】:

    【解决方案5】:

    它应该翻译为“对一个指向常量字符的常量指针的引用”。 这意味着不能为引用的指针分配新的目标地址(指向),并且不能修改它引用的字符串。

    评论后编辑。但后果应该保持不变。

    【讨论】:

    • 它不是一个常量引用,它是一个常量指针的引用。
    • 正确,抱歉。对接近尾声的从右到左的 const 关联感到困惑。
    • @MarcusMüller 常量引用与常量引用相同。甚至标准都在谈论“const reference”,尽管对 const 的引用可能是更好的描述。
    猜你喜欢
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多