c++ 函数声明中的`*&`是什么意思?

bgibtngc  于 12个月前  发布在  其他
关注(0)|答案(8)|浏览(195)

我写了一个沿着这行的函数:

void myFunc(myStruct *&out) {
    out = new myStruct;
    out->field1 = 1;
    out->field2 = 2;
}

字符串
现在在一个调用函数中,我可能会写这样的东西:

myStruct *data;
myFunc(data);


这将填充data中的所有字段。如果我在声明中省略' & ',这将不起作用。(或者更确切地说,它将只在函数中本地工作,但不会改变调用者中的任何内容)
谁能给我解释一下这个“*&”到底是做什么的?它看起来很奇怪,我就是搞不懂它。

w8biq8rn

w8biq8rn1#

C++变量声明中的&符号意味着它是一个reference
它碰巧是一个指针的引用,这解释了你看到的语义;被调用的函数可以在调用上下文中改变指针,因为它有一个指针的引用。
所以,重申一下,这里的“操作符号”不是*&,这个组合本身并不意味着一个整体。*myStruct *类型的一部分,即“指向myStruct的指针“,而&使它成为一个引用,所以你会把它读作“out是指向myStruct的指针的引用“。
在我看来,最初的程序员可以通过将其写为:

void myFunc(myStruct * &out)

字符串
甚至(不是我个人的风格,但当然仍然有效):

void myFunc(myStruct* &out)


当然,关于风格还有很多其他的观点。:)

a8jjtwal

a8jjtwal2#

在C和C++中,&表示通过引用调用;你允许函数改变变量。在这种情况下,你的变量是指向myStruct类型的指针。在这种情况下,函数分配一个新的内存块,并将其分配给你的指针'data'。
在过去(比如K&R),这必须通过传递指针来完成,在这种情况下,是指针到指针或**。引用操作符允许更可读的代码和更强的类型检查。

91zkwejq

91zkwejq3#

解释一下为什么不是&*可能是值得的,但是反过来说,因为声明是递归构建的,所以对指针的引用就像

& out // reference to ...
* (& out) // reference to pointer

字符串
括号是多余的,所以被删除了,但是它们可以帮助你看到这个模式。(要想知道为什么它们是多余的,想象一下这个东西在表达式中是什么样子的,你会注意到首先是地址,然后是解引用-这是我们想要的顺序,括号不会改变)。如果你改变顺序,你会得到

* out // pointer to ...
& (* out) // pointer to reference


指向引用的指针是不法律的。这就是为什么顺序是*&,这意味着“指向指针的引用”。

vof42yt1

vof42yt14#

这看起来像是你在重新实现一个构造函数!
为什么不直接创建一个合适的构造函数呢?
注意在C++中,结构就像一个类(它可以有一个构造函数)。

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;

字符串

v440hwme

v440hwme5#

在C++中,它是一个指向指针的引用,相当于C中指向指针的指针,所以函数的参数是可赋值的。

yh2wf1be

yh2wf1be6#

就像其他人说的那样,&意味着你将引用实际变量到函数中,而不是引用它的副本。这意味着对函数中变量的任何修改都会影响原始变量。当你传递一个指针时,这会变得特别混乱,而指针已经是对其他东西的引用。
如果你的函数签名看起来像这样

void myFunc(myStruct *out);

字符串
会发生的是,你的函数将被传递一个指针的副本。这意味着指针将指向相同的东西,但将是一个不同的变量。在这里,对*out(即out指向的东西)的任何修改都将是永久的,但对out(指针本身)的修改只适用于myFunc内部。
有这样的签名

void myFunc(myStruct *&out);


你声明了函数将引用原始指针。现在对指针变量out的任何更改都会影响传入的原始指针。
话虽如此,

out = new myStruct;


正在修改指针变量out而不是*outout所指向的指针仍然有效,但是现在在堆上创建了一个新的myStruct示例,并且out已被修改为指向它。

vc6uscn9

vc6uscn97#

与C++中的大多数数据类型一样,您可以从右向左读取它,这是有意义的。

myStruct *&out

字符串
out是一个指向myStruct对象的指针(*)的引用(&)。它必须是一个引用,因为你想改变out所指向的对象(在本例中是一个new myStruct)。

kzmpq1sx

kzmpq1sx8#

MyClass * 和MyObject
这里MyObject是指向MyClass的指针的引用。所以调用myFunction(MyClass *&MyObject)是通过引用调用的,我们可以改变指向指针的MyObject。但是如果我们执行myFunction(MyClass *MyObject),我们不能改变MyObject,因为它是通过值调用的,它只会将地址复制到一个临时变量中,这样我们就可以改变MyObject指向的值,而不是MyObject的值。
所以在这种情况下,writer首先为out分配一个新值,这就是为什么需要通过引用调用。

相关问题