Solved

The reference paramter &

Posted on 1998-01-05
10
209 Views
Last Modified: 2010-04-10
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
Comment
Question by:asquarius
  • 7
  • 2
10 Comments
 

Author Comment

by:asquarius
ID: 1177493
Edited text of question
0
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 1177494
Answer comming in a minute or two
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177495
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
 
LVL 22

Expert Comment

by:nietod
ID: 1177496
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
 
LVL 22

Expert Comment

by:nietod
ID: 1177497
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 22

Expert Comment

by:nietod
ID: 1177498
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
 
LVL 22

Expert Comment

by:nietod
ID: 1177499
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
 
LVL 11

Expert Comment

by:alexo
ID: 1177500
It helps some to treat a reference as "another name" of the object.

0
 

Author Comment

by:asquarius
ID: 1177501
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
 
LVL 22

Expert Comment

by:nietod
ID: 1177502
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now