Question about reference

I am learning to use a c++ library, where there is a class called Point, and point has a member function called square. I defined a function as:

1
2
3
4
5
6
7
double coefficient (const Point<dim> &p)
{
  if (p->square() < 0.5*0.5)
    return 20;
  else
    return 1;
}

But the compiler told me should be p.square() instead of p->square. But p is actually a pointer(or reference), so the reference should be used as ->. What's wrong with my code? Thanks a lot!
The problem with your code is in your head. You are not accepting your compiler’s (superior) understanding of the problem.

There are two kinds of reference: direct and indirect. In C++, we use specific language to distinguish the two:

  • an indirect reference is a pointer
  • a direct reference is a reference

Your argument is a (direct) reference, not a pointer.
Hence, you cannot use it like a pointer.

Unless, of course, it is a reference to a pointer, but that is not what you have here.


To add some:

A direct reference (what C++ calls a reference) is an alias for some value —two names for the same object.

1
2
3
4
5
6
  int x = 12;
  int& y = x;  // both "y" and "x" are names for the same int object

  // I can use either name to access the object
  y++;
  std::cout << x << "\n";

An indirect reference (what C++ calls a pointer) is a value that can be used to obtain a direct reference to some other value.

1
2
3
4
5
6
  int x = 12;
  int* p = &x;  // p is a value that can be used to obtain a reference to x

  *p = 7;  // First, I convert p into a direct reference to the x object, then modify it

  std::cout << x << "\n";


I hope helps.
References are not the same as pointers. They can be used in similar ways at times, but are different concepts.

If you're passing an object by reference, essentially you are using the same exact object which was passed into the function.

If you're passing a pointer to an object, you're copying the handle, but have to dereference the handle to get to the actual object.

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
// Example program
#include <iostream>

struct Point {
    Point(double x_param)
    : x(x_param)
    { }
    
    double square() const
    {
        return x * x;   
    }
    
    double x;
};

double coefficient_by_ptr(const Point* p)
{
  if (p->square() < 0.5*0.5)
    return 20;
  else
    return 1;
}

double coefficient_by_ref(const Point& p)
{
  if (p.square() < 0.5*0.5)
    return 20;
  else
    return 1;
}

int main()
{
    Point a(4.2);
    Point b(0.001);
    
    std::cout << coefficient_by_ptr(&a) << '\n'; // passing the address of a
    std::cout << coefficient_by_ref(a) << '\n'; // passing a by reference
    
    std::cout << coefficient_by_ptr(&b) << '\n'; // passing the address of b
    std::cout << coefficient_by_ref(b) << '\n'; // passing b by reference
}


Prefer to use references over pointers unless the problems requires pointer semantics (usually things like trees and linked lists tend towards using pointers).

PS: Note that p->square() and (*p).square() are equivalent when p is a pointer.
Last edited on
Topic archived. No new replies allowed.