C + + 中 * & 和 * * & 的意义

我在函数声明中多次发现这些符号,但我不知道它们的含义。

例如:

void raccogli_dati(double **& V, double **p, int N) {
int ultimo = 3;
V = new double * [N/2];
for(int i=0; i < N/2; i++) {
V[i] = new double[N/2], std :: clog << "digita " << N/2 - i
<< " valori per la parte superiore della matrice V: ";
for(int j=i; j < N/2; j++)
std :: cin >> V[i][j], p[ultimo++][0] = (V[i][j] /= sqrt(p[i][0]*p[j][0]));
}
for(int i=1; i < N/2; i++)
for(int j=0; j < i; j++)
V[i][j] = V[j][i];
}
140391 次浏览

That is taking the parameter by reference. So in the first case you are taking a pointer parameter by reference so whatever modification you do to the value of the pointer is reflected outside the function. Second is the simlilar to first one with the only difference being that it is a double pointer. See this example:

void pass_by_value(int* p)
{
//Allocate memory for int and store the address in p
p = new int;
}


void pass_by_reference(int*& p)
{
p = new int;
}


int main()
{
int* p1 = NULL;
int* p2 = NULL;


pass_by_value(p1); //p1 will still be NULL after this call
pass_by_reference(p2); //p2 's value is changed to point to the newly allocate memory


return 0;
}

That's passing a pointer by reference rather than by value. This for example allows altering the pointer (not the pointed-to object) in the function is such way that the calling code sees the change.

Compare:

void nochange( int* pointer ) //passed by value
{
pointer++; // change will be discarded once function returns
}


void change( int*& pointer ) //passed by reference
{
pointer++; // change will persist when function returns
}

First is a reference to a pointer, second is a reference to a pointer to a pointer. See also FAQ on how pointers and references differ.

void foo(int*& x, int**& y) {
// modifying x or y here will modify a or b in main
}


int main() {
int val = 42;
int *a  = &val;
int **b = &a;


foo(a, b);
return 0;
}

An int* is a pointer to an int, so int*& must be a reference to a pointer to an int. Similarly, int** is a pointer to a pointer to an int, so int**& must be a reference to a pointer to a pointer to an int.

To understand those phrases let's look at the couple of things:

typedef double Foo;
void fooFunc(Foo &_bar){ ... }

So that's passing a double by reference.

typedef double* Foo;
void fooFunc(Foo &_bar){ ... }

now it's passing a pointer to a double by reference.

typedef double** Foo;
void fooFunc(Foo &_bar){ ... }

Finally, it's passing a pointer to a pointer to a double by reference. If you think in terms of typedefs like this you'll understand the proper ordering of the & and * plus what it means.

*& signifies the receiving the pointer by reference. It means it is an alias for the passing parameter. So, it affects the passing parameter.

#include <iostream>
using namespace std;


void foo(int *ptr)
{
ptr = new int(50);    // Modifying the pointer to point to a different location
cout << "In foo:\t" << *ptr << "\n";
delete ptr ;
}


void bar(int *& ptr)
{
ptr = new int(80);    // Modifying the pointer to point to a different location
cout << "In bar:\t" << *ptr << "\n";
// Deleting the pointer will result the actual passed parameter dangling
}
int main()
{
int temp = 100 ;
int *p = &temp ;


cout << "Before foo:\t" << *p << "\n";
foo(p) ;
cout << "After foo:\t" << *p << "\n";


cout << "Before bar:\t" << *p << "\n";
bar(p) ;
cout << "After bar:\t" << *p << "\n";


delete p;


return 0;
}

Output:

Before foo: 100
In foo: 50
After foo:  100
Before bar: 100
In bar: 80
After bar:  80

Typically, you can read the declaration of the variable from right to left. Therefore in the case of int *ptr; , it means that you have a Pointer * to an Integer variable int. Also when it's declared int **ptr2;, it is a *0 * to a *0 * pointing to an Integer variable int , which is the same as "(int *)* ptr2;"

Now, following the syntax by declaring int*& rPtr;, we say it's a Reference & to a &0 * that points to a &1 of type int. Finally, you can apply again this approach also for int**& rPtr2; concluding that it signifies a Reference & to a &0 * to a &0 * to an &5 int.

This *& in theory as well as in practical its possible and called as reference to pointer variable. and it's act like same. This *& combination is used in as function parameter for 'pass by' type defining. unlike ** can also be used for declaring a double pointer variable.
The passing of parameter is divided into pass by value, pass by reference, pass by pointer. there are various answer about "pass by" types available. however the basic we require to understand for this topic is.

pass by reference --> generally operates on already created variable refereed while passing to function e.g fun(int &a);

pass by pointer --> Operates on already initialized 'pointer variable/variable address' passing to function e.g fun(int* a);

auto addControl = [](SomeLabel** label, SomeControl** control) {
*label = new SomeLabel;
*control = new SomeControl;
// few more operation further.
};


addControl(&m_label1,&m_control1);
addControl(&m_label2,&m_control2);
addControl(&m_label3,&m_control3);

in the above example(this is the real life problem i came across) i am trying to init few pointer variable from the lambda function and for that we need to pass it by double pointer, so that comes with d-referencing of pointer for its all usage inside of that lambda + while passing pointer in function which takes double pointer, you need to pass reference to the pointer variable.

so with this same thing reference to the pointer variable, *& this combination helps. in below given way for the same example i have mentioned above.

auto addControl = [](SomeLabel*& label, SomeControl*& control) {
label = new SomeLabel;
control = new SomeControl;
// few more operation further.
};


addControl(m_label1,m_control1);
addControl(m_label2,m_control2);
addControl(m_label3,m_control3);

so here you can see that you neither require d-referencing nor we require to pass reference to pointer variable while passing in function, as current pass by type is already reference to pointer.

Hope this helps :-)