Solved

The reference paramter &

Posted on 1998-01-05
10
208 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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

760 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

19 Experts available now in Live!

Get 1:1 Help Now