Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference, or preferred between ptr** and ptr*& in C++ when calling functions?

Tags:

Is there a difference or preferred way of altering a pointer in a function? Take this snippet for example

    void change(int** ptr) {
        **ptr = 50;
        *ptr = nullptr;
    }

    void change(int*& ptr) {
        *ptr = 50;
        ptr = nullptr;
    }

    int main()
    {
        int a = 5;

        int* ptr = &a;
        int** ptr2 = &ptr;

        std::cout << "value: " << a << std::endl;
        std::cout << "value: " << ptr << std::endl;
        std::cout << "value: " << ptr2 << std::endl;

        change(ptr2);
        //change(ptr);

        std::cout << "value: " << a << std::endl;
        std::cout << "value: " << ptr << std::endl;
        std::cout << "value: " << ptr2 << std::endl;


        system("pause");

    }

It seems like both of the change functions can achieve what I'm asking, but I'm not sure on the difference, other than the reference function doesn't create a copy of the pointer?

like image 915
jjmcc Avatar asked Aug 29 '18 12:08

jjmcc


2 Answers

You can have a null pointer, but not a null reference.

You can supply the first with nullptr, and it will compile1, because there is an implicit conversion from std::nullptr_t to int**. If you tried to supply the second with nullptr, it will fail. The best match would be the conversion std::nullptr_t to int*, but you can't bind a mutable reference to a temporary.

I go over various situations for different ways of parameter passing in this answer, which also includes object ownership considerations (with std::unique_ptr)

1. The behaviour will be undefined, because you dereference it.

like image 152
Caleth Avatar answered Sep 28 '22 05:09

Caleth


Is there a difference ... between ptr** and ptr*& ...

Yes. The former is a pointer, to an object of type ptr*, while the latter is a reference to an object of type ptr*.

or preferred ...

void change(int** ptr) {
    **ptr = 50;
    *ptr = nullptr;
}

void change(int*& ptr) {
    *ptr = 50;
    ptr = nullptr;
}

Advantages of a reference

You'll find that the reference is implicitly indirected, which makes the syntax simpler and that usually helps readability. This is particularly important in case of reference / pointer to a pointer. Same advantage applies to getting a reference: You don't need to use the address-of operator.

Another advantage is that a reference cannot be reassigned to refer to another object. This makes it simpler to read programs that use references, since you don't need to figure out whether a reference is reassigned within a long algorithm; You know that it isn't.

Another advantage is that a reference cannot be null. Therefore you don't need to check for such eventuality within the function. If you pass null to the first example function, the behaviour would be undefined, which is a very bad thing.

Disadvantages of a reference

You'll find that the reference is implicitly indirected. This can be confusing to people who are familiar with only value types (C programmers).

Another disadvantage is that a reference cannot be reassigned to refer to another object. This appears to not be a problem for your function since you don't need to refer to more than one object, but in general, there are situations where it would be useful.

Another disadvantage is that a reference cannot be null. This appears to not be a problem for your function which is presumably never intended to handle such case. But in general, there are situations where you want to represent a referential relation to non-existing object.


Preferences are personal, but in my opinion, the advantages of the reference outweigh the disadvantages, except when you need one of the features that are not possible (nullability, re-assignment)

like image 20
eerorika Avatar answered Sep 28 '22 05:09

eerorika