Thread: References

  1. #1
    Registered User
    Join Date
    Dec 2015
    Posts
    92

    References

    Hello guys, I am trying to understand the implementation of references in C++, after some research and reading this article: An Insight to References in C++ - CodeProject

    I concluded that references act simply as constant pointers (not necessarly implemented by a compiler as constant pointers).

    Also what I tried to understand is a this pointer and functions that return references.

    If I got it right, a this is a pointer variable that points to the address of an object and that address, so by incrementing that address we could get member fields of some object

    Code:
    class Foo 
    {
    public:
    int fooVar;
    int fooVar2; 
    }
    
    Foo fooObj; // For example let's say some Foo obj is at stack address 0x1000
    
    fooObj.fooVar // at address 0x1000 ???
    fooObj.fooVar2; // at address 0x1004 ???
    So this logic would also apply?
    Code:
    // Address Of An Object  0x2000
    // Since it acts as a pointer 
    // I can assign address to reference variable ???
    
    Class& obj = 0x2000; // same as Class* const obj = 0x1000;
    Or if I have two methods
    Code:
    Class* Class::getAddressPointer()
    {
     return this; // returning pointer that points to address where object address is stored???
    }
    Code:
    Class& Class::getAddress()
    {
     return *this; // return address where object is stored???
    }
    Code:
    Class objA;
    Class objB = objA.getAddress(); // I don't think this is valid
    Also in this article C++ Pointers and References

    there is an example:

    Code:
    /* Test passing the result (TestPassResultNew.cpp) */
    #include <iostream>
    using namespace std;
     
    int * squarePtr(int);
    int & squareRef(int);
     
    int main() {
       int number = 8;
       cout << number << endl;  // 8
       cout << squareRef(number) << endl;   // 64
    }
     
    int & squareRef(int number) {
       int * dynamicAllocatedResult = new int(number * number);
       return *dynamicAllocatedResult;
    }
    in function squareRef, we are doing dynamical memory allocation, where address of int object is stored in a variable dynamicAllocatedResult
    so writing
    *dynamicAllocatedResult will dereference pointer and get an integer value,

    but what confuses me that function returns integer reference.

    This line returns an integer value of 64
    Code:
    return *dynamicAllocatedResult;
    And having
    Code:
    int & squareRef(int number)
    equals to the
    Code:
    int* const squareRef(int number)
    ???

    So if a function actually returns const pointer, why are we returning an integer value and not pointer which points to that integer value?

    Is it because compiler does work for us so basically having this line:
    Code:
    return *dynamicAllocatedResult;
    is actually same as this one:
    Code:
    return &dynamicAllocatedResult;
    Thank you in advance!

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,728
    You're over-complicating it, in my opinion. Think of it like this: A pointer is the position of a variable in memory. A reference (in C++ terms) is the variable itself. That's how I view it, and it works pretty well.
    Devoted my life to programming...

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,158
    Quote Originally Posted by High Voltage
    So this logic would also apply?
    Code:
    // Address Of An Object  0x2000
    // Since it acts as a pointer 
    // I can assign address to reference variable ???
     
    Class& obj = 0x2000; // same as Class* const obj = 0x1000;
    No, it wouldn't. The type of the right hand operand would not be compatible with the type "reference to Class". The pointer version wouldn't work either for the same reason. You could get them to compile if you used reinterpret_cast (but for the reference you would need to dereference the pointer resulting from the cast).

    When people say that a reference "acts as a const pointer", they mean that both point/refer to objects, and like how a const pointer cannot be changed to point to another object after initialisation, likewise a reference cannot be bound to another object after being created. Clearly, references and pointers have differences in syntax when declared and when used.

    Quote Originally Posted by High Voltage
    Code:
    Class* Class::getAddressPointer()
    {
     return this; // returning pointer that points to address where object address is stored???
    }
    this is a pointer to the current object. The pointer points to the object. It doesn't point to an address. The value of a pointer is an address. Therefore, getAddressPointer returns a pointer to the current object.

    Quote Originally Posted by High Voltage
    Code:
    Class& Class::getAddress()
    {
     return *this; // return address where object is stored???
    }
    this is a pointer to the current object. The pointer points to the object. Hence, *this is the object itself. Therefore, getAddress returns a reference to the current object.

    Quote Originally Posted by High Voltage
    in function squareRef, we are doing dynamical memory allocation, where address of int object is stored in a variable dynamicAllocatedResult
    so writing
    *dynamicAllocatedResult will dereference pointer and get an integer value,

    but what confuses me that function returns integer reference.
    Since there is dynamic memory allocation, dynamicAllocatedResult points to an int object. Therefore, *dynamicAllocatedResult is the int object itself. Hence, a reference to that int object is returned. Using the object or a reference to the object, you could inspect the object's value, but the pointer points to the object, not its value, and likewise the reference refers to the object, not its value.

    Quote Originally Posted by High Voltage
    So if a function actually returns const pointer, why are we returning an integer value and not pointer which points to that integer value?
    Because the function is declared as returning a reference, not a const pointer, and what is actually returned is an integer object, to which the reference that is actually returned is bound. A reference is not a const pointer; a const pointer is not a reference. They are similiar in a way, a compiler might even implement references as if they were const pointers, but they are not the same thing.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Dec 2015
    Posts
    92
    hope I understood you laserlight well, this is how I see it now
    https://s1.postimg.org/94pu6wotb/Untitled.pngimage hosting 5mb

  5. #5
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I don't ever recommend returning by reference. Especially when it looks like you're receiving a parameter by value and then returning a reference to that. In all likelihood, that's UB. Just return by value.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by High Voltage View Post
    hope I understood you laserlight well, this is how I see it now
    https://s1.postimg.org/94pu6wotb/Untitled.pngimage hosting 5mb
    *this is not 1000. this is a pointer to the class itself, hence *this is the class itself. The class is not an integer, hence that is not valid.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Mar 2016
    Posts
    13

    More fun with result passing

    The C++ Witch clearly explains how things are working related to the original code.

    Here is some more exploration on that last code snippet in the OP. Running the following code shows how both a return to ptr and a return to ref will preserve the address of the int object created on the heap:

    Code:
    #include <iostream>
    using namespace std;
      
    int *squarePtr(int);
    int &squareRef(int);
      
    int main() {
       int number = 8;
       cout << number << '\n' << endl;  
    
       // These preserve the new heap addresses:
       int &int_ref = squareRef(number);
       cout << "Address of int_ref in main:      " << &int_ref << '\n' << endl;
       int *int_ptr = squarePtr(number);  
       cout << "int_ptr in main:                 " << int_ptr << '\n' << endl;   
    
       // This has new address on stack:
       int i = squareRef(number);
       cout << "Address of int i in main:   " << &i << '\n' << endl;    
       
       cout << int_ref << ' ' << *int_ptr << ' ' << i << endl; 
    }
      
    int &squareRef(int number) {
       int *dynamicAllocatedResult = new int(number * number);
       cout << "Address of new int in squareRef: " << dynamicAllocatedResult << endl;
       return *dynamicAllocatedResult;
    }
    
    int *squarePtr(int number) {   
      int *dynamicAllocatedResult = new int(number * number);
      cout << "Address of new int in squarePtr: " << dynamicAllocatedResult << endl;
      return dynamicAllocatedResult;
    }

  8. #8
    Registered User
    Join Date
    Dec 2015
    Posts
    92
    Quote Originally Posted by Elysia View Post
    *this is not 1000. this is a pointer to the class itself, hence *this is the class itself. The class is not an integer, hence that is not valid.
    *this gives us object, but object is just a memory address, as it is any variable in C++, that is what I actually meant, am I right?

    Quote Originally Posted by MutantJohn View Post
    I don't ever recommend returning by reference. Especially when it looks like you're receiving a parameter by value and then returning a reference to that. In all likelihood, that's UB. Just return by value.
    I am aware of that, just trying to understand references

    Quote Originally Posted by GReaper View Post
    You're over-complicating it, in my opinion. Think of it like this: A pointer is the position of a variable in memory. A reference (in C++ terms) is the variable itself. That's how I view it, and it works pretty well.

    Your logic makes sense.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by High Voltage View Post
    *this gives us object, but object is just a memory address, as it is any variable in C++, that is what I actually meant, am I right?
    No, a reference is not a memory address. It's a type that may contain data and functions. Hence it does make sense to treat it as an "int".

    If you're just trying to understand references, then just think of them as aliases. They share storage with the variable they reference. In essence, they're the same variables, but with different names. You don't need to complicate it any further.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Dec 2015
    Posts
    92
    Quote Originally Posted by Elysia View Post
    No, a reference is not a memory address. It's a type that may contain data and functions. Hence it does make sense to treat it as an "int".

    If you're just trying to understand references, then just think of them as aliases. They share storage with the variable they reference. In essence, they're the same variables, but with different names. You don't need to complicate it any further.
    I understood that references can be used as aliases

    Code:
    class Foo
    {
        private:
            int x;
    
        public:
            Foo() : x(0) {}
            int getX() const {return x;}
            void setX(int _x) { x = _x;} 
    };
    
    int main(void)
    {
        Foo foo;
        Foo& fooRef = foo;
         
        printf("fooRef: %d\n", fooRef);
        printf("foo: %d\n", foo);
        
        cout << "foo.getX(): " << foo.getX() << endl;
        cout << "fooRef.getX(): " << foo.getX() << endl << endl;
        
        foo.setX(999);
        cout << "After calling foo.setX(999);" << endl;
        cout << "foo.getX(): " << foo.getX() << endl;
        cout << "fooRef.getX(): " << foo.getX() << endl;
    }
    code produces following

    fooRef: 0
    foo: 0
    foo.getX(): 0
    fooRef.getX(): 0

    After calling foo.setX(999);
    foo.getX(): 999
    fooRef.getX(): 999

    But I think references might share different storage like in this case:

    Code:
    class Test
    {
        int &i;   // int *const i;
        int &j;   // int *const j;
        int &k;   // int *const k; 
    };
    
    int main()
    {    
        // This will print 12 i.e. size of 3 pointers
        cout<<  "size of class Test = "  <<   sizeof(class Test)  <<endl;
        return 0;
    }

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
        printf("fooRef: %d\n", fooRef);
        printf("foo: %d\n", foo);
    This is just undefined behavior. Don't use printf in C++.

    But I think references might share different storage like in this case:
    This doesn't tell you anything.
    This example might be interesting:
    Code:
    std::cout << sizeof(int) << " " << sizeof(int*) << " " << sizeof(int&) << "\n";
    Output (compiled targeting x64): 4 8 4

    So clearly the reference is not an int*. Using sizeof on classes is problematic because the compiler can add padding.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Dec 2015
    Posts
    92
    Quote Originally Posted by Elysia View Post
    Code:
        printf("fooRef: %d\n", fooRef);
        printf("foo: %d\n", foo);
    This is just undefined behavior. Don't use printf in C++.


    This doesn't tell you anything.
    This example might be interesting:
    Code:
    std::cout << sizeof(int) << " " << sizeof(int*) << " " << sizeof(int&) << "\n";
    Output (compiled targeting x64): 4 8 4

    So clearly the reference is not an int*. Using sizeof on classes is problematic because the compiler can add padding.
    Well some people say that references act as they were pointers , and depending on the compiler they could be implemented as pointers or not, maybe your compiler doesn't implement it as pointers and therefore you get different sizeof?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. References
    By Dae in forum C++ Programming
    Replies: 7
    Last Post: 07-23-2009, 03:29 AM
  2. C references
    By Akkernight in forum C Programming
    Replies: 2
    Last Post: 02-27-2009, 07:53 PM
  3. References
    By Lurker in forum C++ Programming
    Replies: 7
    Last Post: 12-23-2003, 12:01 PM
  4. Help via references please!
    By Matt13 in forum C Programming
    Replies: 5
    Last Post: 11-11-2003, 08:09 AM
  5. declare references to references works!
    By ManuelH in forum C++ Programming
    Replies: 4
    Last Post: 01-20-2003, 08:14 AM

Tags for this Thread