2

I've read a quick tutorial aimed for Java developers who want to learn C++. It only explained the basic principles (and syntax) of C++ (I guess). At first I thought, that I had understand everything completely, but while programming C++ something came up that's not really clear to me.

Whats the difference between ...

ExampleClass* doSomething(ExampleClass* ec) {}

and

ExampleClass* doSomething(ExampleClass& ec) {}

and

ExampleClass& doSomething(ExampleClass* ec) {}

and

ExampleClass& doSomething(ExampleClass& ec) {}

?

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
  • Duplicate with http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c – Eregrith Sep 06 '12 at 08:14
  • 14
    Go get [an introductory C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and forget about Java when learning C++. I'm being entirely serious; Java and C++ are only superficially similar. Trying to understand C++ like it's Java is *very* counterproductive. Such a book will talk about pointers and references, which is what your question is about. – In silico Sep 06 '12 at 08:16
  • Just think of references as pointers that cannot change to which object they point to (const pointer) that is automatically dereferenced when you use it. – dtech Sep 14 '12 at 06:39

4 Answers4

1

Pointers and references have similarities. They both point to or reference an object without having space to represent the object value themselves. The pointer however, explicitly uses the * to dereference (as an unary operator), and & to get the address of an object. The * is also used in a different context, to specify a pointer type.

The reference is a somewhat safer "automatic" pointer. A reference however is immutable in the sense that it cannot be later changed to point to something else. A reference also uses the & symbol, but in a different context. Instead of being an unary operator, it is used to specify a reference type.

The 1st example takes a pointer to an ExampleClass and returns a pointer to an ExampleClass object. Eg. you might say:

ExampleClass* doSomething(ExampleClass* ec) {
  return ec;
}
ExampleClass * pointer = new ExampleClass();
ExampleClass * anotherpointer = doSomething(pointer);

In contrast, this following takes a reference to ExampleClass instead. A reference is like a pointer, but it means you don't pass something of pointer type, just pass it straight through, eg:

ExampleClass* doSomething(ExampleClass& ec) {
  return &ec; // & unary operator - get the address of ec
}

ExampleClass obj = ExampleClass();
ExampleClass* pointer = doSomething(obj); // it will automatically get a reference to the input object

The next example takes a pointer and returns a reference instead (notice that the return type is not a pointer):

ExampleClass& doSomething(ExampleClass* ec) {
  // note ec of is type ExampleClass*
  // *ec is of type ExampleClass
  return *ec; // returns a reference to whatever the pointer points to
}
ExampleClass * pointer = new ExampleClass();
ExampleClass& myobj = doSomething(pointer);

You just pass it to a reference object (which points to the object given by the function, ie. doees not make a copy). Note that in this case, the function should take care of making sure there is space allocated for the object, and does not need to explicitly reference (with *) the object in the return statement.

I think you can work out the last example:

ExampleClass& doSomething(ExampleClass& ec) {}

Do note that when returning a reference, you must ensure that the object that is referenced is allocated space outside of the context of a function (eg. as a global, or static local variable), so that it is not destroyed.

You should not return a reference to a local variable, which will be destroyed when the function exits, eg:

ExampleClass& doSomething(ExampleClass* ec) {
  ExampleClass copy = *ec;
  return copy; // WARNING: returning reference to object that will be destroyed
}
ronalchn
  • 12,225
  • 10
  • 51
  • 61
0
ExampleClass* doSomething(ExampleClass* ec) {}

Takes a pointer as parameter, returns a pointer.

ExampleClass* doSomething(ExampleClass& ec) {}

Takes an object by reference and returns a pointer.

ExampleClass& doSomething(ExampleClass* ec) {}

Takes a pointer as parameter and returns a reference.

ExampleClass& doSomething(ExampleClass& ec) {}

Takes an object by reference and returns a reference.

Note that returning by reference is tricky as it can easily result in undefined behavior. Returning a local object by reference is illegal:

ExampleClass& doSomething() 
{
    ExampleClass x;
    return x;
}

This will compile (you might get a warning) but x is destroyed after the function ends so you'll be left with an invalid reference. For this to be valid, x needs to still be alive after the function ends (if it's a class member, until the object itself is destroyed, or it can be a static local, or allocated dynamically).

The same can happen with pointers, although it's less usual:

ExampleClass* doSomething() 
{
    ExampleClass x;
    return &x;
}
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
0

There is no real difference between passing a pointer to an object and passing an object by reference in C++. However passing by reference allows simpler operator overloading syntax and removes the need for lots of ->'s everywhere and should be preferred.

When passing an object by reference it's very common to not want the method to be able to change the object. This is achieved by declaring the object parameter as a const reference (const myClass&).

TheMathemagician
  • 968
  • 9
  • 21
  • I think the differences go further than simplifying operators and avoiding the `->` syntax. You cannot delete a reference to an object like you can a pointer. You cannot have a null reference (undefined behavior otherwise) like you can a null pointer. Thinking ownership semantics, a pointer implies tight ownership of the object whereas a reference implies you can observe/manipulate the object but you don't own it (so you cannot delete it). Also, the standard does not require that references have storage, so assuming references are just syntactical sugar around pointers can be misleading. – Bret Kuhns Sep 06 '12 at 18:03
0
ExampleClass* doSomething(ExampleClass* ec) {}

function do some thing getting value and return value

ExampleClass* doSomething(ExampleClass& ec) {}

function do some thing getting object address in the memory and return value

ExampleClass& doSomething(ExampleClass* ec) {}

function do some thing getting value and return an address of object in the memory

ExampleClass& doSomething(ExampleClass& ec) {}

function do some thing getting and returning object address of object in the memory

Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216