[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 219
  • Last Modified:

The reference paramter &

I need to know some info on '&'.

All I know about it is that it alows you to use a reference parameter as if it was a value parameter. i.e. there is no need for *i = 0 when int * is in the parameter, just use int& with i = 0.

That's what I know.  What I want to know is what is the syntax to assign a parameter passed in as & to a variable.

What I currenetly do is this:

void temp::foo(int *i)
{
    this->i = i;
}

where *i is passed from another class and I can now access it anytime.

what I want to do is

void temp::foo(int &i)
{
   this->i = i;
}

and then access i without the need for *i.

Also, if an object is created with new, how can I pass it into a function.  will

void temp2::foo()
{
   temp *p_temp = new temp();
   foo2(*p_temp);
}

where foo2 is
void temp2::foo2(temp& p_temp);

and if so, how can I delete p_temp from within foo2.
will delete p_temp work?

also when an object is passed in as "(temp & p_temp)", how can I check it's validity.  That is if it was "(temp * p_temp)" I would do

if (p_temp == NULL)

what is the equivalent?

thanks a lot
0
asquarius
Asked:
asquarius
  • 7
  • 2
1 Solution
 
asquariusAuthor Commented:
Edited text of question
0
 
nietodCommented:
Answer comming in a minute or two
0
 
nietodCommented:
First of all, the way I like to think about references (&'s) is that they are implimented as pointers, but treated as objects (variables).  In other words, the compiler will generate the exact same regardless of whethor you use references or pointers.  This means there is no advantage or disavantage to using references over pointers in the final product.  However, in the source code, that is, in what you read and write, there is a difference.  When you use references, the source code appears like you are using an object or variable dirrectly, unlike a pointer.  For example.

foo(int &i,int *j)
{
   i = 0; // looks like you have "i", really you have a pointer.
   *j = 0; // obviously you have a pointer.
}

anyways, that's how I think about it.  Now to answer your questions.  In the next comment...
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
nietodCommented:
Although pointers and references are implimented the same (the compiler produces the same code) there are differences in their use.  To be specific, there are some restrictions on references that are not pointers.  This is because references appear to be variables, not pointers.

One difference is that a reference cannot be reassigned.  By this I mean that the thing that is refered to cannot be changed, what is stored in the thing that is referred to can be changed.  For example, in the following code I reassign a pointer from i to j.

int i;
int j;
int &IntRef = i;
int *IntPtr = &i;

IntPtr = &j; // Point to j instead.

However IntRef cannot be reassigned, that is will always refers to i.  If I do

IntRef = j;

I will copy j's value to IntRef (and also to i, since they are the same thing)  However, IntRef will still refer to i, not to j.

Another difference is that pointers can be NULL.  References cannot be NULL.  A NULL pointer is understood to point to nothing.  But a reference always appears to be something, again the way I think about it is that when you have a reference you appear to have the object, that is, it appears to be a variable.  You cann't have an object that is non-existant (NULL).

Now in slight contrast to what I just said, you could use the address operator to get arround this, like.

foo(int &i)
{
   if (&i != NULL)
     // do something
   else
     // there was no i passed.
}

This, however, would be considered poor programming (at least by me, and I suspect many others).

0
 
nietodCommented:
To answer you last question (I'm not going in order).  You should not check to see if a reference passed in is NULL (above I showed how, but don't do it)  Use references whenever a value must always be passed.  Use pointers when NULL can be passed in some cases.  

This may seem inconvenient.  for example, if the code within the procedure access the value many times it would be nice to use a reference rather than a pointer (because it is easier to read)
For these cases, create the reference in the procedure when you know you actually have the value, for example,

foo (int *IntPtr)
{
   if (IntPtr)  // If something was passed.
   {
      int &IntRef = *IntPtr; // Create reference.
     
      // use IntRef as if it were an integer.
   }
}

0
 
nietodCommented:
Now for your first question:

what I want to do is

void temp::foo(int &i)
{
   this->i = i;
}

and then access i without the need for *i.

it depends on what you mean, it depends, on how you declared i within the class temp.  I am guessing that you want to use i like a pointer, that is, it must point to different things.  If so, you must use a pointer.  As I said above you cannot reassign a reference so you can't declare i as a reference in the class (the parameter i can be).  (Note when this is inconvenient, you can use the technique I used above to declare a local reference that uses the current value of i.)

If you meant somethign else, please try to explain again.
0
 
nietodCommented:
To answer your question about pointers created by new (or any other pointer).  Remember my motto that refereces acts (syntactically) like regular objects (not pointers).

a procedure that is written like

FooRef(int &i)

seems to be the same as

FooDir(int i)

they will be called the same.

int i;
int *IPtr = new int;

FooDir(i);
FooRef(i); // the same as above.
FooDir(*IPtr);
FooRef(*IPtr); // the same as above.


Hope this helps.
0
 
alexoCommented:
It helps some to treat a reference as "another name" of the object.

0
 
asquariusAuthor Commented:
nietod wrote:

Now for your first question:
  what I want to do is
     void temp::foo(int &i)
     {
        this->i = i;
     }

  and then access i without the need for *i.

it depends on what you mean, it depends, on how you declared i within the class temp. I am guessing that you want to use i like a pointer.


What I want to do is define a global reference in my class header and define it in a function.

something like:

class test
{
    &i;

    void fooAssign(&i);
    void fooUse();
}

then have a function

void test::fooAssign(int& i)  //i is passed in from another class
{
   this->i = i;   //assigned once
}

void test::fooUse()
{
   i++;
}

now everywhere that points to the original i passed in the function fooAssign has a new value.

by pointers I would have done

class test
{
   int *i;

   void fooAssign(int *i);
   void fooUse();
}

void fooAssign(int *i)
{
   this->i = i;
}

void fooUse()
{
   (*i)++;
}

this is ugly as far as I am concerned but does have the desired effect of changing the data held at the memory address of i (as you know).
0
 
nietodCommented:
How could I write 20 pages of answer and still miss my point?

You can declare a reference type member in a class or structure, like

class test
{
   &i;
};

however, there is a restriction.  Since references must be initialized when they are defined, the class or strucure must have a constructor that initializes the reference, like

class test
{
   &i;
   test(int IniInt) : i(IniInt) {};
};

also note that the reference cannot be changed once the class is constructed (I know I at least made this point).  What I mean is that you cannot change what "i" refers to, thus

void fooAssign(int &i)
{
   this->i = i;
}

is not going to change what i refers to.  It will change the value that is stored in what i refers to.

In conclussion, you cannot create an object that uses a reference that refers to different things.  However you can create objects of the same type where different objects refer to defferent things.  However, you cannot change what an object refers.

If you must change the reference, you must use a pointer.  If that is too ugly you can make it neater by using a local reference (which will probably be optimized away so there is no harm)

Say you have a member IPtr that points to the current integer.  If you have a section that uses the integer extensively, you can declare a local reference to it like this

   {
      int &IntRef = *IPtr;

      ++IntRef;
      // Use IntRef in other ways.
   }
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 7
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now