0

Can you give me an example when I can't pass argument by reference and I need to use pointer. I've found an example, but I'm not sure.

Suppose you have a class D derived from the base class B. You need pointer if you want do so:

void function(B* b){...}
int main{
  D* d;
  function(d);
}
Ruggero Turra
  • 16,929
  • 16
  • 85
  • 141
  • 1
    You could use a reference in your example. – JoshD Oct 14 '10 at 21:02
  • 1
    i asked the equivalent question just recently http://stackoverflow.com/questions/3835741/are-reference-and-pointer-equal-with-regards-to-polymorphism – pm100 Oct 14 '10 at 21:03

8 Answers8

6

The single time where you can not use a reference and must use a pointer is if you allow the concept of "no argument" by passing a null pointer.

However, you might want to use pointers as arguments when you are actually storing a pointer to whatever was passed. Most C++ developpers will notice that you aren't using a reference and pay special attention to what your documentation says.

André Caron
  • 44,541
  • 12
  • 67
  • 125
  • One might argue that you even then don't *need* a pointer, if you write an object that has a nullable state. But whatyever. – John Dibling Oct 14 '10 at 21:40
  • Yes, but not all objects are nullable, especially when you're using RAII :-) – André Caron Oct 14 '10 at 23:16
  • @John Dibling: I am not that fan of the Nullable concept (at least built in), I much prefer the `boost::optional` hook, in order to distinguish by type what can and cannot be null. – Matthieu M. Oct 15 '10 at 07:10
6

If there is a coding guideline (like Google's) that says to use pointer arguments, then that's what you do.

Otherwise, only declare your own function with pointer formal argument when

  • a nullpointer is a valid & meaningful actual argument, or

  • the actual argument is most naturally pointer already, or

  • you're going to store that pointer somewhere.

Possibly more cases, but I think you get the drift: when you have a choice (no coding guideline saying otherwise), prefer references.

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • +1 for "the actual argument is most naturally pointer already" . Obvious example is that once you're talking about iterating, your concern is as much about where you are in the sequence as what object in the sequence you are looking at. E.g. http://stackoverflow.com/questions/3909784/how-do-i-find-a-particular-value-in-an-array-and-return-its-index/3909788#3909788 . – Brian Oct 14 '10 at 21:08
1

Another case: if the thing you're passing is the last argument before varargs:

void fn1(A &a, ...); // Uh oh
void fn2(A *a, ...); // Good

I don't know if this is required by the standard, or is just a bug in the implementation of the C++ compiler I use.

Michael
  • 1,022
  • 6
  • 7
  • The Standard only says that variable arguments must be the last argument, or maybe that there must be one preceeding argument. The type of that argument is definitely not mentioned. – Puppy Oct 15 '10 at 21:50
  • A POD type right before `...` is not required in terms of declaring or defining a function, but it is necessary to usefully get those arguments back using `va_start()`. 18.7p3: "If the parameter [of `va_start`] is declared with a function, array, or reference type, or with a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined." – aschepler Oct 15 '10 at 22:03
  • Also, in this situation, I recommend creating an implicit conversion from `class A` to a POD struct which contains an `A*` pointer, and using that as the last named argument, so that users can call the function as if the first argument type were really `A` (or related reference). – aschepler Oct 15 '10 at 22:06
  • Indeed. The trouble I had was getting the arguments out, not declaring, or even calling, the function. Thanks for clearing up why that's the case, and for the record in MSVC++ 2005, "undefined" means "doesn't work" in this particular case, if you use a reference. – Michael Oct 16 '10 at 04:33
1

Typically, you use pointers for one of two things:

  • Reassignability - you can't rebind a reference.
  • Null pointers - there's no such thing as a null reference.

If your intended use case does not need either of those two properties, use a reference. Else, use a pointer.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

If you want to allow the lack of an object, you need to use pointers:

// This allows DoSomething to receive pointers to NULL, which cannot
// be done with references
void DoSomething(Something *pSomething)
{
  if (pSomething)
  {
    ...
  }
}

int main()
{
  Something *pSomething=NULL;

  DoSomething(pSomething);
}
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
0

http://www.daniweb.com/forums/thread216353.html

Singly linked lists example were pointers and pointer of pointers are used as function parameters.

Jacob Nelson
  • 2,946
  • 5
  • 33
  • 41
-1

the only reason is if you need to pass null. I.e you want to call the function saying 'I haven't got one of those'

pm100
  • 48,078
  • 23
  • 82
  • 145
-2

I think that if you want to pass a function, you have to pass it by pointer. I don't see how you can pass the function by reference.

For example, take the following function:

#include <iostream>
#include "math.h"

void myfun (double value, size_t nofloops, double (*function)(double))
   {
   std::cout << value << std::endl;
   for (size_t i=0;i<nofloops;++i)
      {
      value = function(value);
      std::cout << value << std::endl;
      }
   std::cout << "------------------" << std::endl;
   }

void main()
   {
   myfun(100,10,sin);
   myfun(100,10,cos);
   myfun(100,10,sqrt);
   }

The function in this small utility executes the given function a number of times, taking the result as input in the next iteration. I can't see how you can pass the function by reference.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • 1
    -1 for `void main`, which is invalid in both C and C++ (and has never been valid in either language).Re passing by reference: simply replace `(*function)` with `(&function)`. That's it. :-) Cheers & hth., – Cheers and hth. - Alf Oct 15 '10 at 05:10
  • PS: When you pass a function by reference you get a very odd beast (that's probably why you thought it couldn't be done), a *read only reference*. It's not a reference to const, but you can't assign to it. Because you can't assign to a function, and when you think of a reference as just an alias, another name, then this makes sense. – Cheers and hth. - Alf Oct 15 '10 at 05:15
  • Apparently, some older C compilers allow "void main". See http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/legality-of-void-main.html. – Patrick Oct 15 '10 at 07:01