在C++中,pass-by-pointer更适合传递引用?

sky*_*oor 34 c++

我可以想象一种情况,其中输入参数可以是NULL,因此传递指针是首选但不是传递参考?

任何人都可以添加更多案例吗?

RC.*_*RC. 39

有些人喜欢在传递对象实际上要修改的情况下更好地传递指针.当对象通过引用传递时,它们使用pass-by-const-reference以避免对象的副本,但不会在函数中更改.

在插图中,请执行以下功能:

int foo(int x);
int foo1(int &x);
int foo2(int *x);
Run Code Online (Sandbox Code Playgroud)

现在在代码中,我执行以下操作:

int testInt = 0;

foo(testInt);   // can't modify testInt
foo1(testInt);  // can modify testInt

foo2(&testInt); // can modify testInt
Run Code Online (Sandbox Code Playgroud)

在调用foo vs foo1时,从调用者角度(或读取代码的程序员)来看,该函数可以修改testInt而不必查看函数的签名.查看foo2,读者可以很容易地看到该函数实际上可能会修改testInt的值,因为该函数正在接收参数的地址.请注意,这并不能保证对象实际被修改,但是在使用引用和指针时保持一致有帮助.通常,如果要始终如一地遵循此准则,则应始终在要避免复制时传递const引用,并在希望能够修改对象时传递指针.

  • 这是一个非常好的观点.你是完全正确的.作为一个程序员,我通常不会指望`foo1(testInt)`永远修改foo1,如果函数调用后testInt不同会有点惊讶(尽管我最终通过检查函数定义来弄清楚它) .但是使用`foo2(&testInt)`,很明显testInt可以被函数修改.很好的答案.我认为这是一个特别重要的标准,在自动完成(显示函数定义)等工具不可用的情况下采用,例如在教科书中. (5认同)
  • 我发现"你知道它是否可以改变"的论点是一个弱者.为什么你编写的函数如此不透明,你需要猜测哪些参数会被修改?对于初始编写,您必须有可用的定义来告诉您哪个需要指针,所以显然它没有那么多. (5认同)
  • 你忘了提及我想要传递`NULL`的情况,这对于引用来说是不可能的,无论是不是`const`(你应该在你的讨论中提出的另一件事是关于期望事情是或不是被调用者修改并执行额外步骤强制执行,如果我们要去那条路.):)最重要的是,你忘了提到`operator =`对指针和引用的影响! (4认同)
  • 我认为引用的"不能为NULL"属性在函数签名中比在函数是否可以修改引用(或指向)参数时更为重要.因为该语言允许通过引用传递给可修改的对象,所以您永远不会受到约定的完全保护.当您使用指针发出可能为null的信号时,它会准确记录您的检查位置.如果在任何地方都使用指针,则必须记录指针必须为空的位置作为前置条件(不太健壮),或者对许多不需要它们的函数添加额外的空值检查. (3认同)

Tho*_*ini 23

对于这个问题,C++ FAQ有一个非常好的答案:

尽可能使用引用,并在必要时使用指针.

只要您不需要"重新安装",引用通常优先于指针.这通常意味着引用在类的公共接口中最有用.引用通常出现在对象的皮肤上,而指针则出现在内部.

上面的例外是函数的参数或返回值需要"sentinel"引用 - 一个不引用对象的引用.这通常最好通过返回/获取指针,并给出NULL指针这一特殊意义(引用应始终别名对象,而不是取消引用的NULL指针).

注意:旧的C语言程序员有时不喜欢引用,因为它们提供了调用者代码中不明确的引用语义.然而,在一些C++经验之后,人们很快意识到这是一种信息隐藏形式,这是一种资产而不是责任.例如,程序员应该用问题的语言而不是机器的语言编写代码.


Abh*_*hay 6

在现实世界编程中有许多情况,其中参数不存在或无效,这可能取决于代码的运行时语义.在这种情况下,您可以使用NULL(0)来表示此状态.除此之外,

  • 可以将指针重新分配给新状态.参考不能.在某些情况下这是可取的.
  • 指针有助于转移所有者的语义.这在多线程环境中尤其有用,如果参数状态用于在单独的线程中执行,并且通常不会轮询直到线程退出.

虽然如果花费足够的时间来正确设计代码,可以避免这些情况; 在实践中,每次都不可能.