开发者

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

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

#include "stdafx.h"
#define BOOST_TEST_MODULE example
#incl开发者_如何转开发ude <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?


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.


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.


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) { ... }


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 What are the differences between a pointer variable and a reference variable in C++?


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.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜