Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Returning a Reference

Returning a Reference

Scheduled Pinned Locked Moved C / C++ / MFC
comdebugginghelptutorialquestion
12 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Anthony Mushrow

    I've come across a situation where I don't understand entirely what's happening regarding references (not pointers). If we did this for example:

    int someNumber = 5;

    int& get()
    {
    return someNumber;
    }

    void main()
    {
    int a = get(); //a = 5
    get() = 52; //someNumber = 52
    int b = get(); //b = 52, obviously
    }

    We can change the value of some number by setting the return value of get() (or the long way around int& ref = get(); ref = 52;) But, in this case I'm not sure what exactly is going on:

    class bclass
    {
    public:
    bclass(){}
    virtual void cheese()=0;
    bclass(const bclass& other){ _asm{int 3} }
    };

    class dclass : public bclass
    {
    public:
    dclass(){val=5;}
    void cheese() { _asm{int 3} }
    dclass(const dclass& other){ _asm{int 3} }

    int val;
    

    };

    dclass base;

    bclass& get()
    {
    return base;
    }

    void main()
    {
    dclass argh;
    argh.val = 2;
    get() = argh; //copy constructors not called, no error messages, base.val = 5
    get().cheese();
    }

    What happens when we try to set the return value of get()? Why doesn't anything happen? I also tried it with just references to bclass so simply trying to set a reference to a bclass to a reference of a different bclass and still nothing. Also, before anybody says anything I'm not actually trying to set the return value to something else, or set any other variables in some bizarre manner it's just something I've come across quite by accident. EDIT: Or a much simpler example:

    bclass& argh = d2();
    bclass& hmm = dclass();
    hmm = argh;
    hmm.cheese();

    Where dclass's implementation of cheese is called

    My current favourite phrase: I've seen better!

    -SK Genius

    Source Indexing and Symbol Servers[^]

    T Offline
    T Offline
    TheGreatAndPowerfulOz
    wrote on last edited by
    #3

    What you're trying to do is reassign the reference, which you can't do. It's a common mistake to make. What is actually occurring is the operator= is being called, but since you don't supply an implementation, it calls the compiler generated one. The compiler generated one essentially does nothing (EDIT: in this case). For primitive values, like in your first example, works like you would think because it's just transferring values. You can "reassign" the reference like this:

    &get() = &argh;

    "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

    modified on Thursday, January 27, 2011 1:59 PM

    E N 2 Replies Last reply
    0
    • T TheGreatAndPowerfulOz

      What you're trying to do is reassign the reference, which you can't do. It's a common mistake to make. What is actually occurring is the operator= is being called, but since you don't supply an implementation, it calls the compiler generated one. The compiler generated one essentially does nothing (EDIT: in this case). For primitive values, like in your first example, works like you would think because it's just transferring values. You can "reassign" the reference like this:

      &get() = &argh;

      "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

      modified on Thursday, January 27, 2011 1:59 PM

      E Offline
      E Offline
      Emilio Garavaglia
      wrote on last edited by
      #4

      &get() = &argh ... I understand what you mean but ... is that legal C++ or just a hack around a (sort of) compiler bug? There is nothing like that in the c++ reference book!

      2 bugs found. > recompile ... 65534 bugs found. :doh:

      S T 2 Replies Last reply
      0
      • A Anthony Mushrow

        I've come across a situation where I don't understand entirely what's happening regarding references (not pointers). If we did this for example:

        int someNumber = 5;

        int& get()
        {
        return someNumber;
        }

        void main()
        {
        int a = get(); //a = 5
        get() = 52; //someNumber = 52
        int b = get(); //b = 52, obviously
        }

        We can change the value of some number by setting the return value of get() (or the long way around int& ref = get(); ref = 52;) But, in this case I'm not sure what exactly is going on:

        class bclass
        {
        public:
        bclass(){}
        virtual void cheese()=0;
        bclass(const bclass& other){ _asm{int 3} }
        };

        class dclass : public bclass
        {
        public:
        dclass(){val=5;}
        void cheese() { _asm{int 3} }
        dclass(const dclass& other){ _asm{int 3} }

        int val;
        

        };

        dclass base;

        bclass& get()
        {
        return base;
        }

        void main()
        {
        dclass argh;
        argh.val = 2;
        get() = argh; //copy constructors not called, no error messages, base.val = 5
        get().cheese();
        }

        What happens when we try to set the return value of get()? Why doesn't anything happen? I also tried it with just references to bclass so simply trying to set a reference to a bclass to a reference of a different bclass and still nothing. Also, before anybody says anything I'm not actually trying to set the return value to something else, or set any other variables in some bizarre manner it's just something I've come across quite by accident. EDIT: Or a much simpler example:

        bclass& argh = d2();
        bclass& hmm = dclass();
        hmm = argh;
        hmm.cheese();

        Where dclass's implementation of cheese is called

        My current favourite phrase: I've seen better!

        -SK Genius

        Source Indexing and Symbol Servers[^]

        S Offline
        S Offline
        Stefan_Lang
        wrote on last edited by
        #5

        get() = argh; calls bclass::operator= which doesn't exist*. Even if it did exist, val is not a member of bclass and thus couldn't be copied anyway. If you define the return type of get() as dclass&, and in addtion to that define the assignment operator for this class, then it might work. P.S.: to my knowledge assignment operators can't be made virtual, but you might be able to get this to work with a trick like this:

        class base {
        virtual void assign(const base& other)=0; //<- helper function
        public:
        base& operator=(const base& other) { assign(other); return *this; }
        };
        class derived : public base {
        virtual void assign(const base& other) {
        const derived* pOther = &(dynamic_cast<const derived&>(other));
        if (pOther != 0) {
        val = pOther->val;
        }
        }
        public:
        derived() : val(5) {}
        int val;
        };
        derived myglobalderived; // val is initialized to 5
        derived& get() { return myglobalderived; }
        void test() {
        derived mylocalderived;
        mylocalderived.val = 3;
        get() = mylocalderived;
        std::cout << "get() = " << get().val;
        }

        *P.P.S: while bclass::operator= hasn't been defined explicitely, the compiler might create one automatically (but it wouldn't make any difference as explained above). I am not sure in this case however, since assignment operators can't be virtual, and bclass is an abstract class. A member-wise copy will not make any sense, as you can't create instances for an abstract class, and derived classes will overwrite, not override the assignment operator.

        modified on Thursday, January 27, 2011 5:58 AM

        1 Reply Last reply
        0
        • T TheGreatAndPowerfulOz

          What you're trying to do is reassign the reference, which you can't do. It's a common mistake to make. What is actually occurring is the operator= is being called, but since you don't supply an implementation, it calls the compiler generated one. The compiler generated one essentially does nothing (EDIT: in this case). For primitive values, like in your first example, works like you would think because it's just transferring values. You can "reassign" the reference like this:

          &get() = &argh;

          "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

          modified on Thursday, January 27, 2011 1:59 PM

          N Offline
          N Offline
          Niklas L
          wrote on last edited by
          #6

          ahmed zahmed wrote:

          The compiler generated one essentially does nothing.

          It does copy all members of the class by using each members assignment operator, default or explicitly declared and implemented.

          home

          S T 2 Replies Last reply
          0
          • N Niklas L

            ahmed zahmed wrote:

            The compiler generated one essentially does nothing.

            It does copy all members of the class by using each members assignment operator, default or explicitly declared and implemented.

            home

            S Offline
            S Offline
            Stefan_Lang
            wrote on last edited by
            #7

            Since bclass's oeprators are being called, only members of bclass are being copied, i. e. nothing. See my edit on my previous response.

            N 1 Reply Last reply
            0
            • S Stefan_Lang

              Since bclass's oeprators are being called, only members of bclass are being copied, i. e. nothing. See my edit on my previous response.

              N Offline
              N Offline
              Niklas L
              wrote on last edited by
              #8

              It was more of a clarification of what seemed to be a general statement that could be interpreted as "a default assignment operator does nothing".

              home

              S 1 Reply Last reply
              0
              • N Niklas L

                It was more of a clarification of what seemed to be a general statement that could be interpreted as "a default assignment operator does nothing".

                home

                S Offline
                S Offline
                Stefan_Lang
                wrote on last edited by
                #9

                I see. I didn't read it as a general statement, but I now recognize it might be considered as such. Good point.

                1 Reply Last reply
                0
                • E Emilio Garavaglia

                  &get() = &argh ... I understand what you mean but ... is that legal C++ or just a hack around a (sort of) compiler bug? There is nothing like that in the c++ reference book!

                  2 bugs found. > recompile ... 65534 bugs found. :doh:

                  S Offline
                  S Offline
                  Stefan_Lang
                  wrote on last edited by
                  #10

                  Just to clear up some of the confusion: To the compiler, a reference is equivalent to a pointer in everything but the method of dereferencing. It treats the reference as a pointer to a memory location that occupies the contents of some variable. To the programmer, a reference is equivalent to an alias. Through that reference you can manipulate the contents of another variable without knowing it's orginal name, by using an alternate name. Your method get() effectively returns a temporary alternate alias to your globale variable. You can assign this to a variable of type reference to bclass (bclass&) in order to use that variable as an alias to your global variable, or, like you did, you can just use the temporary alias immediately. ahmed's suggestion was that you can reassign the alias to another variable, in this case the local variable argh. But it wouldn't work as the address of operator itself is not a reference, and therefore get() is not an l-value. Reassigning a variable of type reference to another variable is not possible.

                  1 Reply Last reply
                  0
                  • N Niklas L

                    ahmed zahmed wrote:

                    The compiler generated one essentially does nothing.

                    It does copy all members of the class by using each members assignment operator, default or explicitly declared and implemented.

                    home

                    T Offline
                    T Offline
                    TheGreatAndPowerfulOz
                    wrote on last edited by
                    #11

                    You do make a good point, so I edited my response to clarify. Thanks for keeping me honest.

                    "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

                    1 Reply Last reply
                    0
                    • E Emilio Garavaglia

                      &get() = &argh ... I understand what you mean but ... is that legal C++ or just a hack around a (sort of) compiler bug? There is nothing like that in the c++ reference book!

                      2 bugs found. > recompile ... 65534 bugs found. :doh:

                      T Offline
                      T Offline
                      TheGreatAndPowerfulOz
                      wrote on last edited by
                      #12

                      no, it's not legal, it was just an attempt to clarify what he was attempting to do.

                      "If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups