-1

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

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++ 给出了这个编译错误:

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. 我相信当我尝试将“未命名变量”传递给参考参数时会显示此错误。在这种情况下,我正在传递变量ptr,这应该不是问题。
  1. ptr作为参数传入,因为该函数具有有用的返回值。设置ptr更像是这个功能的副产品,调用者可以选择忽略或使用。

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

4

2 回答 2

2

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

您的第二个示例int Foo(const Obj* &ptr)完全按照预期工作,并且如果您制作DoSomethingconst 则可以正常编译。

评论你的三个想法:

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

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

#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();
}
于 2021-10-29T07:50:12.637 回答
-2

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

于 2021-10-29T03:50:46.973 回答