我写了一个函数:
void myFunc(myStruct *&out) {
out = new myStruct;
out->field1 = 1;
out->field2 = 2;
}
现在在调用函数中,我可能会写这样的东西:
myStruct *data;
myFunc(data);
将填充data
中的所有字段。如果我省略声明中的“&
”,则无效。 (或者更确切地说,它只能在函数中本地工作,但不会改变调用者中的任何内容)
有人可以向我解释一下这个“*&
”究竟是做什么的吗?它看起来很奇怪,我对它没有多大意义。
答案 0 :(得分:36)
& C ++变量声明中的符号表示它是reference。
它恰好是对指针的引用,它解释了你所看到的语义;被调用的函数可以改变调用上下文中的指针,因为它有一个对它的引用。
因此,重申一下,这里的“操作符号”不是*&
,这种组合本身并不意味着很多。 *
是myStruct *
类型的一部分,即“指向myStruct
的指针”,&
使其成为引用,因此您将其视为“{{ 1}}是对指向out
“。
在我看来,原始程序员可以通过将其编写为:
来帮助myStruct
甚至(不是我的个人风格,但当然仍然有效):
void myFunc(myStruct * &out)
当然,关于风格还有很多其他的看法。 :)
答案 1 :(得分:13)
在C和C ++中,&意思是指参考;您允许该函数更改变量。 在这种情况下,您的变量是指向myStruct类型的指针。在这种情况下,函数会分配一个新的内存块并将其分配给指针'data'。
在过去(比如K& R),这必须通过传递一个指针来完成,在这种情况下是一个指针指针或**。引用运算符允许更可读的代码和更强大的类型检查。
答案 2 :(得分:6)
这看起来像是在重新实现一个构造函数!
为什么不创建适当的构造函数?
注意在C ++中,struct就像一个类(它可以有一个构造函数)。
struct myStruct
{
myStruct()
:field1(1)
,field2(2)
{}
};
myStruct* data1 = new myStruct;
// or Preferably use a smart pointer
std::auto_ptr<myStruct> data2(new myStruct);
// or a normal object
myStruct data3;
答案 3 :(得分:6)
可能值得解释为什么它不是&*
,反之亦然。原因是,声明是递归构建的,因此对指针的引用就像
& out // reference to ...
* (& out) // reference to pointer
括号被删除,因为它们是多余的,但它们可以帮助您查看模式。 (为了了解它们为什么是多余的,想象一下这个东西在表达式中是怎样的,你会注意到首先是地址,然后是解除引用 - 这就是我们想要的顺序,括号不会改变)。如果你改变订单,你会得到
* out // pointer to ...
& (* out) // pointer to reference
参考指针不合法。这就是订单为*&
的原因,这意味着“引用指针”。
答案 4 :(得分:3)
在C ++中,它是对指针的引用,类似于指向C中指针的指针,因此函数的参数是可赋值的。
答案 5 :(得分:3)
void myFunc(myStruct *out);
会发生什么事情,你的函数将传递一个指针的副本来使用。这意味着指针指向同一个东西,但它将是一个不同的变量。这里,对*out
所做的任何修改(即出点是什么)都是永久性的,但对out
(指针本身)所做的更改只适用于myFunc
。有这样的签名
void myFunc(myStruct *&out);
您声明该函数将引用原始指针。现在,对指针变量out
所做的任何更改都将影响传入的原始指针。
话虽如此,该行
out = new myStruct;
正在修改指针变量out
而不是*out
。无论out
曾经指向的是什么仍然活着,但是现在已经在堆上创建了一个新的myStruct实例,并且out
已被修改为指向它。
答案 6 :(得分:2)
请参阅wikipedia
答案 7 :(得分:2)
与C ++中的大多数数据类型一样,您可以从右向左阅读它,这是有意义的。
myStruct *&out
out
是指向&
对象的指针(*
)的引用(myStruct
)。它必须是参考,因为您想要更改out
指向的内容(在本例中为new myStruct
)。
答案 8 :(得分:1)
MyClass *&amp; MyObject
这里MyObject引用了MyClass的指针。所以调用myFunction(MyClass *&amp; MyObject)是通过引用调用的,我们可以更改MyObject,它引用了一个指针。但是如果我们执行myFunction(MyClass * MyObject),我们无法更改MyObject,因为它是按值调用的,它只是将地址复制到临时变量中,因此我们可以更改MyObject指向但不是MyObject的值。
所以在这种情况下,编写者首先分配一个新值,这就是为什么需要通过引用进行调用。