0

If a C++ class member function requires a pointer to an object as an argument, is it considered bad practice to pass by reference?

The following code, for example, will work, however without the pass by reference it becomes a dangerous code, and will lead to catastrophic errors at runtime.

class ClassA
{
public:
    void SetPointer(const ClassB& classb) // Remove 1 ampersand and serious errors will occur
    {
        if(ptr_to_classb == nullptr) // Initialized to nullptr in constructor
            ptr_to_classb = &classb;
        else
            throw(...); // Throw some error
    }

private:
    ClassB* ptr_to_classb;
}

Consider if passing by value, and a copy of the argument was made, that this would be disastrous when dereferencing at a later time.

The alternative is this:

class ClassA
{
public:
    void SetPointer(const ClassB* const classb)
    {
        if(ptr_to_classb == nullptr) // Initialized to nullptr in constructor
            ptr_to_classb = (ClassB*)(classb);
        else
            throw(...); // Throw some error
    }

private:
    ClassB* ptr_to_classb;
}

I like consistency, to defaulted to the first type, however I suspect that the second form is considered to be better practice. Is this the case?

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • Pass by pointer...... – Cool_Coder Aug 10 '14 at 11:25
  • Both will work, however I personally prefer the pointer. If a function will keep a reference to the object after it has returned, I use a pointer as a reminder for when I call the function. – Neil Kirk Aug 10 '14 at 11:27
  • "If a C++ class member function requires a pointer to an object as an argument, is it considered bad practice to pass by reference?" - if a function requires a pointer and you pass it a non-pointer, then it won't even compile. So, if it takes a pointer, call it with a pointer. If it takes a reference, call it with a reference. Simple as that. – The Paramagnetic Croissant Aug 10 '14 at 11:28
  • @TheParamagneticCroissant That doesn't answer the question. – FreelanceConsultant Aug 10 '14 at 11:29
  • @user3728501 it does. If OP did not **mean** what he wrote, that's his problem. – The Paramagnetic Croissant Aug 10 '14 at 11:30
  • 1
    @TheParamagneticCroissant I think he means that the underlying logic of the function requires a pointer, and he is not sure if the function should take a pointer or a reference. – Peter Clark Aug 10 '14 at 11:31
  • 2
    @PeterClark If it **requires** a pointer, then nothing else but a pointer will suffice. If it requires to **modify** the argument, then both will do. If the he doesn't want to make a copy of the argument, again both a (const) pointer and reference will do the trick. It is unfortunately ambiguous which of the three alternatives OP is looking for. – The Paramagnetic Croissant Aug 10 '14 at 11:33
  • @TheParamagneticCroissant It does not _*require*_ a pointer, however a pointer is required in the function for assignment to a pointer variable. An alternative question is: "Is it better to make the pointer (take the address of) when passing the argument or is it better to pass a reference to an object and take the address within the function." You appreciate that both produce the same result? By question is which is considered better practice? – FreelanceConsultant Aug 10 '14 at 11:36
  • @user3728501 What's the matter with your usage of `const`? The parameter is a reference/pointer to `const`, while the member is not `const`. It will not work; use `const` for both or none. – anatolyg Aug 10 '14 at 11:57
  • @anatolyg I don't understand what you're getting at here? – FreelanceConsultant Aug 10 '14 at 12:46
  • @user3728501 It is forbidden to assign a pointer-to-const to a pointer-to-non-const (demo [here](http://ideone.com/j4592V)). I guess you don't need `const` in your method declaration. – anatolyg Aug 10 '14 at 13:02
  • @anatolyg That's a mistake, there should be a type-cast there, thanks for pointing that out. – FreelanceConsultant Aug 10 '14 at 13:05
  • Anyone care to explain the close vote? – FreelanceConsultant Aug 10 '14 at 13:06
  • Close vote: what kind of objective criteria do you expect ? I cannot see any. The only difference between pointer and reference is re-seatability (blurred by `std::reference`) and nullity; those are objective. So you usually pick the best tool for the job, but here for the sake of [a foolish consistency](http://www.goodreads.com/quotes/353571-a-foolish-consistency-is-the-hobgoblin-of-little-minds-adored) you ask us to pick one or the other *forever* ? The premise is shaky, I cannot think of any objective answer, I would rather see this question closed. – Matthieu M. Aug 10 '14 at 13:23
  • @MatthieuM. Sorry I didn't realize it was against SO rules to ask for advice or what the accepted standards are. – FreelanceConsultant Aug 10 '14 at 15:03
  • Actually, if there was *one* accepted Standard it would not be against SO rules because the response would be objective :) It's just that SO does not wish to attract sterile debates, and subjective questions usually end up as such with everyone firmly camped on their original positions :/ – Matthieu M. Aug 10 '14 at 15:10
  • @MatthieuM. I don't see any sterile debates, other than the one we are having now. – FreelanceConsultant Aug 10 '14 at 15:28
  • I don't see any useful answer either though; and the only answer with an upvote refers you to [http://stackoverflow.com/questions/7058339/c-when-to-use-references-vs-pointers](http://stackoverflow.com/questions/7058339/c-when-to-use-references-vs-pointers), and repeats it. But then that is why closing a question requires 5 votes, so that no single opinion may close one; I think it should be closed, but maybe there's only 2 of us thinking so... or maybe it's just a matter of time. – Matthieu M. Aug 10 '14 at 16:03
  • @MatthieuM. That other question has almost nothing to do with this one, and did not pop up when I searched google, stackoverflow.com. I think that this would be useful to others in the future. Any question which is not should be closed. Also I now have an answer to my question, which is that in this case a reference is better because it would be desirable to avoid the user passing `nullptr` as an argument. – FreelanceConsultant Aug 10 '14 at 16:10

3 Answers3

1

Well, both approaches are correct and fine but in your case it will be probably better to go with pointers, since a reference variable can only be assigned a value at initialization unlike pointers. With the same pointer you could later pass a different class object.

Savail
  • 867
  • 10
  • 27
1

My view is that if passing a null argument to the method is a valid thing to do (i.e. the logic that the method executes would be valid with a null pointer), then use a pointer. If the argument should never be null then use a reference.

In your case this depends on whether it is valid for ClassA::ptr_to_classb to be null. Since you throw if ptr_to_classb is already set (meaning you don't ever want to change what it points to) you might even want to conside storing a reference instead and passing that in the constructor of ClassA, getting rid of ClassA::SetPointer.

There are some other opinions on reference vs pointer here as well.

Community
  • 1
  • 1
Peter Clark
  • 2,863
  • 3
  • 23
  • 37
0

Your method just sets a field of your object, so it seems you want to use the type of the field (which is pointer, not reference). You wrote

I like consistency, to defaulted to the first type

which, I guess, refers to the rule "use references when possible; use pointers oterwise". I think your case is an exception from this rule, because the declaration

void do_stuff(ClassA& object)

usually means "do stuff on the object, and forget about it", and your case is different.

anatolyg
  • 26,506
  • 9
  • 60
  • 134