views:

235

answers:

5

Isn't a pointer just a reference when you don't de-reference it?

#include "stdafx.h"
#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>


std::list<int>* user_defined_func( ) {
    std::cout << "BEGIN: user_defined_func" << std::endl;
    std::list<int>* l = new std::list<int>;

    l->push_back(8);
    l->push_back(0);

    std::cout << "END: user_defined_func" << std::endl;

    return l;
}


bool validate_list(std::list<int> &L1)
{

   std::cout << "BEGIN: validate_list" << std::endl;

   std::list<int>::iterator it1 = L1.begin();

   for(; it1 != L1.end(); ++it1)
   {
      if(*it1<= 1){

         std::cout << "Validation failed because an item in the list was less than or equal to 1." << std::endl;
         std::cout << "END: validate_list" << std::endl;
         return false;
       }
   }

   std::cout << "Test passed because all of the items in the list were greater than or equal to 1" << std::endl;
   std::cout << "END: validate_list" << std::endl;
  return true;
}

BOOST_AUTO_TEST_SUITE( test )
BOOST_AUTO_TEST_CASE( test )
{
   std::list<int>* list1 = user_defined_func();
   BOOST_CHECK_PREDICATE( validate_list, (list1) );
}
BOOST_AUTO_TEST_SUITE_END()

In the line,

BOOST_CHECK_PREDICATE( validate_list, (list1) ); 

above, I was told that I can't pass pointer to the function expecting reference. I thought that a pointer (that hasn't been de-referenced) was just an address (i.e. a reference). What am I missing here?

+6  A: 

You have it the wrong way round - references may be implemented using pointers (though you shouldn't normally think about that), but pointers in C++ are not references. You may be getting confused because in C, passing things using pointers is called "call by reference", but that's because C doesn't have real references like C++ does.

anon
And the reason for the downvote was....
anon
You dint' provide any extra explanation. Just stating that pointers aren't references is not enough, the OP saw that already. He was probably expecting an explanation of "how" and "why".
Pop Catalin
@Pop If we are going to start downvoting answers that don't exactly fulfill individual users expectations, few of us will have any rep left at all. This is a technical web site, and downvotes should be reserved for technical errors.
anon
It wasn't a technical error, but lack of technical explanation. I reserve downvotes for answers I find insufficient as a minimum explanation for a question.
Pop Catalin
But why do you care really, you have enough people to approve you even if there are some that disapprove (for various reasons, like mine).
Pop Catalin
@Pop Well, that confirms my opinion of you. I care because I worry I may have made a technical error that the downvoter has spotted but decided not to tell me about.
anon
+1, thanks Neil.
Simucal
+1  A: 

While references are usually implemented as pointers under the hood, the language treats them as two separate concepts. There are some important distinctions between the two:

  1. References must be bound at initialization time and can not be re-bound to refer to a different object, while pointers may point to different addresses at different times.
  2. Pointers may be NULL, but references must always be bound to an object.
Nick Meyer
+2  A: 

I would say that a reference is more like a compiler handled pointer.

With a regular pointer you have complete control over the reference, you can reassign it, delete it, invert a few bits.. whatever.

With a reference the compiler handles the pointer and you are given an object you do not have to dereference but it still a pointer to the same object.

to make your code work you would need to do

BOOST_CHECK_PREDICATE( validate_list, (*list1) );

but I am sure you already knew that :)

I think this question and answer is along the same lines http://stackoverflow.com/questions/57483/difference-between-pointer-variable-and-reference-variable-in-c/57492#57492

Charles
@Charles That does not fix the code in my posting above. I've already tried that.
leeand00
@Charles I'm using Visual Studio 2005, does that have something to do with it?
leeand00
hmm, well it is a boost test macro, maybe there is a special boost utility function you need to use to dereference the pointer
Charles
+11  A: 

Pointers and references are similar, but different in several ways:

  1. They have different access syntax. If you have T* a and T& b, you access member variables and functions using a->member and b.member respectively.
  2. Pointers can point to nothing, while references must always point to something. a = 0 is legal, but b = 0 or anything to that effect is not.
  3. Pointers can be "reseated" (i.e. the pointee may be changed) whereas references cannot. a = &b is legal, but int c; b = c; is not (T& b = c is, however -- references may only be set at their initialization). (Thanks Mike D.)
  4. Pointers cannot refer to temporaries, but const references can.
  5. Pointers can point to other pointers, (T**) but references cannot refer to other references (i.e. there's no such thing as T&&, although note that C++0x will be using T&& to define move semantics). As a result, you cannot have arrays of references. (Thanks AshleysBrain)

One might wonder why we have references at all, and not just use pointers all the time (like in C). The reason is because of operator overloading or certain operators.

Consider the assignment operator. What would the function syntax be without references? If it were T* operator=(T* lhs, T rhs) then we'd have to write things like:

int a(1);
&a = 2;

Essentially, references allow us to have functions of l-values without the need for pointer reference and dereference syntax.

Peter Alexander
Actually, `b = *a` is perfectly legal, but it performs a copy and doesn't reseat the reference. As for `operator=(T* lhs, T rhs)`, the compiler could hide the ``. (Some coding standards would demand an `if(!lhs) {handle error}` block, too.) Ugly all around. Personally, I like refs because they communicate to other devs that I'm not reseating.
Mike D.
+1 to Mike D, but no vote for this answer until `b = *a` is described correctly!
Daniel Earwicker
Just a warning, while `T) Also, references might be dangling! I still don't understand why it was decided that there would be 2 invocations styles (`.` and `->`) while one seemed perfectly sufficient!
Matthieu M.
Another difference: you can have a pointer to a pointer, but not a reference to a reference. As a result, you can have a vector of pointers, but not a vector of references.
AshleysBrain
@Mike D. )
Peter Alexander
+3  A: 

Isn't a pointer just a reference when you don't de-reference it?

No, a pointer contains a value that is interpreted as a memory address. (Whether it contains a value that is actually a valid memory address is another question)

A reference is an alias, another way of referring to an existing value.

int i = 5;
int* p = &i; // The value in p is the address that i is stored at.
int& r = i;  // The value in r is 5, because r is an alias of i.
             //   Whenever you use r, it's as if you typed i, and vice versa.
             //   (In this scope, anyway).

int sum = i + r; // Identical to i + i or r + i or r + r.

Edit:

since list1 is a pointer, how do I access the reference...?

You have two choices. You can derefence the pointer to get at the list it points to:

std::list<int>* list1 = user_defined_func();
std::list<int>& list1ref = *list1;
BOOST_CHECK_PREDICATE( validate_list, list1ref );
delete list1;

Of course, this could be shortened to:

std::list<int>* list1 = user_defined_func();
BOOST_CHECK_PREDICATE( validate_list, *list1 );
delete list1;

Your validation function could take a pointer instead of a reference (remember to change L1.{something} to L1->{something}):

bool validate_list(std::list<int>* L1) { ... }
Bill
From user_defined_func( ) I get back a pointer to a list that it has created.So this pointer is returned to the list1 pointer variable in my BOOST_AUTO_TEST_CASENow since list1 is a pointer, how do I access the reference of the (object?) that the list1 pointer points to?
leeand00
@leeand00: Good question. I've edited my post with my answer.
Bill
@Bill Okay, I needed to change my validate_list function so that it took a pointer instead of a reference. That cleared it up. It's been a while since I've done C++ and I didn't remember or wasn't ware that there was a difference between a reference and a non-dereferenced pointer.
leeand00