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

时间:2010-03-31 03:46:14

标签: c++

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

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

13 个答案:

答案 0 :(得分:39)

在传递的对象实际上将被修改的情况下,有些像pass-by-pointer更好。当对象通过引用传递时,它们使用pass-by-const-reference来避免对象的副本,但不会在函数中更改。

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

int foo(int x);
int foo1(int &x);
int foo2(int *x);

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

int testInt = 0;

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

foo2(&testInt); // can modify testInt

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

答案 1 :(得分:20)

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

  

尽可能使用参考,和   必要的指针。

     

参考文献通常优先于   任何你不需要的指针   “重新安装”。这通常意味着   引用在a中最有用   class的公共接口。参考   通常出现在皮肤上   对象和内部的指针。

     

以上例外是a   函数的参数或返回值   需要一个“哨兵”参考 - a   不参考的参考文献   宾语。这通常最好通过   返回/拿指针,给予   NULL指针这个特殊   意义(引用应始终   别名对象,而不是取消引用的NULL   指针)。

     

注意:老C线程序员有时候   因为他们不喜欢参考   提供不是的参考语义   在调用者的代码中显式。后   但是,有一些C ++经验   很快意识到这是一种形式   信息隐藏,这是一种资产   而不是责任。例如。,   程序员应该编写代码   问题的语言而不是   机器的语言。

答案 2 :(得分:6)

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

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

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

答案 3 :(得分:4)

除了关于所有权语义的其他一些答案(特别是工厂函数)。

虽然不是技术原因,但常见的样式指南要求是任何可以修改的参数都应该通过指针传递。这使得在调用现场很明显可以修改对象。

void Operate(const int &input_arg, int *output_arg) {
  *output_arg = input_arg + 1;
}

int main() {
  int input_arg = 5;
  int output_arg;
  Foo(input_arg, &output_arg);  // Passing address, will be modified!
}

答案 4 :(得分:4)

规则编号为1:如果NULL是函数上下文中函数参数的有效值,则将其作为指针传递,否则将其作为参考传递。

基本原理,如果它不能(不应该!)永远为NULL,那么不要因为它是NULL而不必检查NULL或冒问题。

答案 5 :(得分:1)

在处理原始内存时(例如,如果创建自己的内存池),您需要使用指针。但是你是对的,在普通代码中,指针的唯一用途是可选参数。

答案 6 :(得分:1)

在C ++中,在大多数情况下几乎不需要通过指针。您应该首先考虑替代方案:模板,(const)引用,容器,字符串和智能指针。也就是说,如果你必须支持遗留代码,那么你需要使用指针。如果您的编译器是简约的(例如,嵌入式系统),您将需要指针。如果你需要与一个C库(一个你正在使用的非常特殊的驱动程序的某种类型的系统库)交谈,那么你需要使用指针。如果你想处理非常特殊的内存偏移,那么你需要指针。

在C指针中是一流的公民,他们在考虑消除它们时过于根本。

答案 7 :(得分:1)

随时传递函数指针。 或者如果你有一个“重置”方法a la auto_ptr。

答案 8 :(得分:1)

当您需要操作(例如调整大小,重新分配等)函数内指针指向的地址时,您需要一个指针。

例如:


void f( int* p )
{
    // ..

    delete []p;
    p = new int[ size ];

    //...
}

与引用不同,指针的值可以更改和操作。

答案 9 :(得分:1)

这不是特定的参数传递,但确实会影响参数传递。

您可以拥有指针的容器/聚合,但不能包含引用。虽然引用是多态的,但只有指针支持“更新”操作,这对于容器使用是必不可少的(特别是因为你还不能大量初始化引用,不确定C ++ 0x聚合初始化器是否会改变它)。

因此,如果你有一个装满指针的容器,你通常最终会使用接受指针而不是引用的函数来管理它。

答案 10 :(得分:0)

可以想象,可以编写一个函数来对内存执行某些操作,例如重新分配它以使其更大(返回新指针)。

答案 11 :(得分:0)

如果我需要传递一个对象数组,我需要通过指针传递。数组并不总是存储在std::vector<>

除此之外,传递指针允许NULL并且通过引用传递不会,因此我将这种区别用作SQL中的NULLNOT NULL列的契约,并且松散地像“函数返回booltrue =成功且false =失败,而函数返回int:返回值是结果代码,其中0 =成功和其他是失败“。

答案 12 :(得分:0)

谷歌似乎对此有强烈的看法,我倾向于同意:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments