将对象作为函数中的引用或指针传递

时间:2011-12-01 08:53:22

标签: c++ pointers reference

我知道问题“当指针何时引用”或“通过引用传递参数或通过指针传递参数”已被多次询问。但是,我的印象是,在某些情况下,我读过:“当你想要修改它时,你应该通过指针将一个Object传递给一个函数”。如果最后一句完全正确,有人会说,解释并证明其合理性吗?

或者换句话说,是不是可以通过引用来修改对象?

6 个答案:

答案 0 :(得分:4)

如果要更改指针指向的对象,则应将对象作为双指针传递,例如将对象从一个内存位置移动到另一个内存位置时:

void foo (obj **x) {
  delete *x;
  obj *y = (obj *) some_new_address;
  *x = y; // change what x points to
}
...
obj *x = new obj();
foo(&obj);
// obj now points to another location

有了参考,你不能这样做。

答案 1 :(得分:4)

为方便起见,我将引用一个被函数修改为“out-param”的参数。

Out-params可以作为非const引用传递。没有技术理由不这样做。例如,在标准库中,std::swap通过引用获取两个参数并修改它们。

我过去曾经看过,作为一种风格指南中的规则,out-params必须通过指针传递而不是通过引用传递。这背后的动机是有些人[*]想要一个出现的函数调用来按值传递对象,以保持对象不被修改。这使得他们更容易通过查看调用代码来推理一段代码,而无需查看函数实际执行的操作。例如:

int foo(int a) {
    return a + 1;
}
int bar(int &a) {
    return ++a;
}

现在,给定int i = 0;,调用foo(i)bar(i)看起来完全相同,但其中一个行为就像一个漂亮的简单C函数,而另一个使用pass-by -reference修改i

有些人[*]希望这些不同的内容在呼叫网站上明显不同,因此他们更愿意编写bar(&i)来明确i可以修改[**] 1}}。基本上,他们更喜欢C ++根本没有非const引用作为函数参数。

这些人想要做的事情并不一定有任何问题。例如,总是使用std::swap,您可以在std::iter_swap的情况下坚持使用它。但大多数C ++风格指南都没有这样的规则。

[*]例如C程序员

[**]实际上在我的bar函数中,a既是in-param又是out-param。他们的首选函数int bar(int *pa);在技术上没有外派,尽管为方便起见,他们可能会将pa(即i)的referand称为out-param每个人都知道这意味着什么。

答案 2 :(得分:2)

你引用的句子是规范性的,也就是说,它告诉你你应该"应该"做,而不是你能做什么"或"不能"做。因此,这是一种风格问题,需要进行辩论。我个人不接受。

当然可以通过(非const)引用来修改对象。

答案 3 :(得分:1)

当然可以通过引用修改对象。也许你引用的句子是关于C的,没有引用?

指南是这样的:

  • 如果你想修改参数而调用者可能不提供它,请通过指针传递(并传递NULL,0或 nullptr 表示没有对象)。
  • 如果要修改参数,则必须将对象传递给函数 - 通过引用传递。
  • 如果您不想修改参数但调用者可能不提供它,请通过const指针
  • 否则,如果通过const引用复制传递对象很昂贵,如果没有,则按值传递。
  • 新功能 - 如果要在函数内复制参数(例如,在构造函数中传递字符串以初始化字段)并使用符合C ++ 11的编译器(支持移动构造函数),则按值传递。

答案 4 :(得分:0)

您可以通过引用和指针两种方式修改对象。如果您不想修改,可以使用const修饰符。

答案 5 :(得分:0)

要将变量作为out参数传递,可以将其作为引用和指针传递。如果变量的寿命超过其范围,请尝试仅使用指针。例如。将指针从函数返回给被调用者。

在某些情况下,如果无法在堆栈上分配内存,则使用指针并在堆上分配内存。再次可以通过指针或引用将指针传递给函数作为out参数。