value vs reference

I am having trouble understanding pointers/references/values. Why wouldnt you just use always values most of the time, and if speed is needed, use references. At that point what is the use of pointers?
They appear to be roughly the same speed of references. And the syntax for references are much simpler.

im still not sure why even use references. It seems like passing by value would be best, as in simplest. It doesnt even seem that slow to begin with, working with a billion ints, did it only 1.5 (ish) seconds slower. That doenst seem significant

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

int value_add(int n){
    n++;
    return n;
}

void reference_add(int &n){
    n++;
}

void pointer_add(int *n){
    (*n)++;
}

int main(int argc,char **argv){
    int num = 0;
    int loopcount = 1000000000;
    if (argc >= 2){
        std::string arg1 = argv[1];
        if (arg1 == "-v"){
            std::cout << "value" << std::endl;
            for (int i=0; i<loopcount; i++){
                num = value_add(num);
            }
        }
        else if (arg1 == "-r"){
            std::cout << "reference" << std::endl;
            for (int i=0; i<loopcount; i++){
                reference_add(num);
            }
        }
        else if (arg1 == "-p"){
            std::cout << "pointer" << std::endl;
            for (int i=0; i<loopcount; i++){
                pointer_add(&num);
            }
        }
    }
    else{
        std::cout << "program requires 1 argument\n";
    }
    std::cout << "num is: " << num << std::endl;

}


output of the 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
metulburr@ubuntu:~/programs/cplusplus$ g++ test2.cpp -o test2
metulburr@ubuntu:~/programs/cplusplus$ time ./test2 -v
value
num is: 1000000000

real	0m5.018s
user	0m5.008s
sys	0m0.000s
metulburr@ubuntu:~/programs/cplusplus$ time ./test2 -r
reference
num is: 1000000000

real	0m3.309s
user	0m3.304s
sys	0m0.000s
metulburr@ubuntu:~/programs/cplusplus$ time ./test2 -p
pointer
num is: 1000000000

real	0m3.365s
user	0m3.360s
sys	0m0.000s
metulburr@ubuntu:~/programs/cplusplus$ 
Last edited on
1.5 seconds is significant when dealing with time sensitive functions.

You are right, passing by value is the simplest and easiest to understand. With smaller projects it probably would not make much of a difference.

Pointers would be used if you had something like a large 3d object that needed to be passed. If you pass a copy of it, it would require an enormous over head. First you are passing the data, then you will need to allocate more memory for the copies of that data, then returning yet again more allocated space(if you return that is) where-else pointers just say "hey, we need this and it is over there" vs sending you all the data. Kinda like someone giving you a URL address vs someone emailing you the whole dang website. With large enough data, it makes a BIG difference.

References are easier on the syntax level, however due to their notation it makes it harder for people reading your code to understand what you are doing. Also, references have to be declared on initialization. This can be a disadvantage. I think pointers are just cooler.
The compiler is not allowed to optimize pass-by-value into pass-by-reference, and the different in speed is extremely noticeable in most cases.

Pointers are rarely used anymore, now we have lots of things like smart pointer classes and RAII, so references are all we need.

Also, besides passing by const reference, think of passing by non-const reference so you can change the value given to you. Try writing std::swap ;)
Why wouldnt you just use always values most of the time,


For basic types like int... you should.

and if speed is needed, use references.


References are not necessarily faster. In fact passing a basic type like an int by reference may be slower than passing it by value.

At that point what is the use of pointers?


2 main things:

1) They can point to an array
2) They can point to null (ie, they can be optional)




Passing by value

Passing by value creates a copy of the passed parameter. For basic types like int, this is cheap and fast, and therefore should be preferred for "input" parameters in functions.

The downside is that copying larger, more complex types like std::strings, or std::vectors, etc can be expensive. For example copying a vector involves allocating a new buffer to hold all the contents, then copying each individual element over to the new buffer.

If the vector has thousands of elements, you can see how this might get costly.

Passing by const reference

Passing by const reference (void func( const std::vector<T>& v )) does not create a copy, but lets you access the original object through a reference. However since the reference is const, it prevents you from modifying it... allowing the calling code to pass objects without fear that they'll be modified by the function.

This works well for large objects like vectors... but not necessarily for small types like int. Passing a reference is like passing a pointer a lot of the time... and passing a pointer means the function has to dereference it every time it access it... which is extra work. Whereas if it was passed by value, there would not need to be any dereference.


Passing by pointer

This can typically be used for 2 things. #1 is for passing variable size arrays:

1
2
3
4
5
6
7
8
9
10
11
12
void addOne(int* foo, int size)
{
    for(int i = 0; i < size; ++i)
        foo[i] += 1;
}

int main()
{
    int array[5] = {1, 2, 3, 4, 5};

    addOne( array, 5 );
}


And #2 is for "optional" output parameters. Since a pointer can be null... this gives you the option of passing "nothing" whereas with a reference you have to actually give it an object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void doSomething( int* someoutput )
{
    // ... do stuff here

    if(someoutput)
        *someoutput = foo;
}

int main()
{
    int foo;
    doSomething( &foo );   // here, I care about the output

    doSomething( nullptr );  // here, I don't care
}
Pointers are very important and they are probably the greatest things about c++. As you should know pointers point to an address in memory. Now this gives the programmer the ability to do a lot of optimization to his program. Not only can he set a value to a specific memory address but he can also get information that will otherwise be hard to obtain with regular references. Also with pointers you are not copying a variable but actually going to where the variable is stored in memory making you programs run smoother.
I suggest you do some more research about pointers because, trust me when you start to write big programs and I mean thousands of line of code, you will make great use of them.

Kinda like someone giving you a URL address vs someone emailing you the whole dang website.

nice analogy, thanks

References are easier on the syntax level, however due to their notation it makes it harder for people reading your code to understand what you are doing. Also, references have to be declared on initialization. This can be a disadvantage. I think pointers are just cooler.

i am not sure i follow. How would it make it harder to read rather than pointers? I think if i had the choice of coolor and simple, i would choose simple over cooler any day.
Last edited on
Because if you pass a value to a function you do not know if it is a reference or a value you are passing without looking at someone's function headers.

I would choose cooler over simpler any day IMO.

You can easily pour a glass of water BUT, it is much cooler to go get a slushy!

Yeah, I know that was dumb.
oh i just saw everyones post just now. Didnt see them before.

Ok thanks. I seem to understand it. But when i go to use it in practice i often forget it, because i dont use it that much.
Topic archived. No new replies allowed.