我可以引用 C++ 中的指针吗?

Can I take a reference of a pointer in C++?

我将 对指针变量的引用 传递给函数。该函数将做一些事情并将指针变量指向某个对象。代码:

int Foo(Obj* &ptr) {
  // do something...
  ptr = some_address;
  return return_value;
}

int main() {
  Obj* p = nullptr;
  int ret = Foo(p);
  // do something with ret
  p->DoSomething();
}

但是,如果我想将对 指针的引用传递给 const,事情就会变得更加棘手。我希望更改指针变量本身(因此引用),但我不希望使用此指针更改指向的 Obj 实例。在我的想象中,它应该是这样的:

int Foo(const Obj* &ptr) {
  // do something...
  ptr = some_address;
  return return_value;
}

int main() {
  const Obj* p = nullptr;
  int ret = Foo(p);
  // do something with ret
  p->DoSomething(); // this should only work when DoSomething() is const method
}

编辑:以下错误无法重现,因此被删除。本题关注的是指针引用的概念,而不是解决一个问题

C++ gives this compile error:

main.cpp:22:10: error: cannot bind non-const lvalue reference of type ‘const Obj*&’ to an rvalue of type ‘const Obj*’
   22 |     Foo(ptr);
      |         ^~~
main.cpp:14:23: note:   initializing argument 1 of ‘void test(const Obj*&)’
   14 | int Foo(const Obj* &ptr) {
      |         ~~~~~~~~~~~~^~~

一些想法:

无法重现错误

  1. I believe this error is shown when I am trying to pass in an "unnamed variable" into a reference parameter. In this case I am passing the variable ptr, which shouldn't be an issue.
  1. ptr作为参数传入是因为函数有一个有用的return值。设置ptr更像是这个函数的副产品,调用者可以选择忽略或使用

  2. 我也可以尝试使用Obj**作为参数,它是通过指针传递而不是通过引用传递。当 const Obj** 作为参数传递时,此方法有效。我只是想知道如果参数通过引用传递会怎样。

处理这种情况的一种方法是使用 typedefusing。例如,using ObjPtr = Obj*; 现在函数将是 int Foo(const ObjPtr& ptr) { ... }.

我不确定你的问题是什么,因为给出的错误代码与你的代码不匹配。

您使用 int Foo(const Obj* &ptr) 的第二个示例完全按预期工作,如果您使 DoSomethingconst.

可以正常编译

评论你的三个想法:

  1. 如果你 const 正确,错误就会消失。
  2. 我真的非常不喜欢这样的参数。 return 一个结构或一对 int 和指针要干净得多。这样调用者就可以编写 const auto[ret, p] = Foo(); 而不必明确声明您可能不想使用的指针。
  3. 将指针传递给指针是 C 风格的,因为缺少引用,只会让代码更难阅读,没有任何好处。

下面是经过稍微修改的代码,可以正常编译,也有更好的 Foo,正如我对 2 的回答中提到的:

#include <utility>

struct Obj
{
    void DoSomething() const;
};

// This is ugly of course, used just to have a valid ptr to return
Obj global;

int Foo(const Obj* &ptr) {
  // do something...
  ptr = &global;
  return 5;
}

std::pair<int, const Obj*> BetterFoo()
 {
  // do something...
  return {5, &global};
}

int main() {

  const Obj* p1 = nullptr;
  int ret1 = Foo(p1);

  const auto[ret2, p2] = BetterFoo();

  p1->DoSomething(); 
  p2->DoSomething();
}