Thread: object return type

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    48

    object return type

    Hello, I recently started learning C++ using the 'teach yourself in 21 days' tutorials, and I have hit a little snag in my understanding. I've been ignoring it for the time being in hope that it will click later on but upon reaching the operator overloading section I feel I need to understand this now.

    Here is some code of what I am working on...

    Code:
    #include <iostream>
    
    using namespace std;
    typedef unsigned short int USHORT;
    
    class Counter
    {
        public:
          Counter();
          ~Counter() {}
          USHORT GetItsVal() const {return itsVal;}
          void SetItsVal(USHORT x) {itsVal = x;}
          const Counter& operator ++ ();
    
        private:
          USHORT itsVal;
    };
    
    Counter::Counter():
    itsVal(0)
    {};
    
    
    const Counter& Counter::operator ++ ()
    {
        ++itsVal;
        return *this;
    }
    
    
    
    int main()
    {
        Counter i;
        cout << "The value of i is " << i.GetItsVal() << endl;
        ++i;
        cout << "The value of i is " << i.GetItsVal() << endl;
        Counter a = ++i;
        cout << "The value of a is " << a.GetItsVal() << endl;
        cout << "The value of i is " << i.GetItsVal() << endl;
        ++a;
        cout << "The value of a is " << a.GetItsVal() << endl;
        cout << "The value of i is " << i.GetItsVal() << endl;
        return 0;
    }
    There is nothing wrong with the code, but there is one thing I cannot get to grips with and that is a member function(or any other function for that matter) returning an object.

    This example is prevelant due to the overloaded prefix operator function returning a reference to a Counter object, specifically the dereferenced 'this' pointer.

    I can understand a return value being an integer, but I'm having trouble understanding an entire object being returned, especially when a member function returns a different object, I am unsure of how to use them.

    Like I said I have ignored this until now. In the example a counter is created (i) and using the overloaded prefix function, somehow a reference to a counter is returned, the 'this' pointer points to the calling object so there is a reference to 'i' itself returned but where does it go? it is not used, I am confused.

    Secondly when creating the counter 'a', it is said to equal ++i. Now I am really confused. The ++ increments 'i' and then returns itself as being equal to 'a', so 'a' is a copy of 'i'... this is confusing enough but if the return value is a reference also, is 'a' now not a reference to 'i'? This is obviously not the case but thats as far as I can get at my point of understanding.

    Could somebody please clarify this for me.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    Counter a = ++i;
    ++i returns an object by const reference, which is returned to the calling program. That "temporary" object is then handed to the copy constructor (in this case, since this is a declaration of the variable a). You didn't write a copy constructor, and when that happens you get one "for free" which does a very basic "copy the value of every member variable into the new object".

    If instead you had done
    Code:
    Counter a;
    a = ++i;
    you would have called the regular constructor first, then operator= on the next line. You didn't write operator= either, but that is also something you get "for free". It does essentially the same thing.

    Once the end of this line is reached, the "temporary" const reference that was created by ++i is destroyed. i still exists, of course, and a is a new object that is a copy of it.

    The semantics of returning an object by const reference are essentially that the object returned is, well, const: it can't be assigned to. So you couldn't try something like
    Code:
    ++i = a;

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    48
    I am still a little bit confused, I thought that by passing by reference you are eliminating the copy constructor, as no local copies are made.

    If the return value of the function is a reference to the i counter itself, where does the copy constructor come into play?

    I am obviously getting something mixed up here, does the = operator in this situation invoke the copy constructor and just say that 'a' is a copy of 'i' after its 'itsVal' variable is incremented?

    I'm lost

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MattJ812 View Post
    I am still a little bit confused, I thought that by passing by reference you are eliminating the copy constructor, as no local copies are made.
    Since we're not discussing pass by reference (to the post-increment function), the objection is irrelevant and immaterial.

    Quote Originally Posted by MattJ812 View Post
    If the return value of the function is a reference to the i counter itself, where does the copy constructor come into play?
    Because that's what "Counter a =" is. It's not an assigment, and it certainly doesn't magically make "a" a reference. If you wanted to make "a" a reference, you'd have to declare it as such, i.e. with
    Code:
    Counter &a =++i;
    What you have is syntactic sugar for
    Code:
    Counter a(++i);

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    AND: I was thinking that the automatic copy constructor would take an object, rather than a reference -- but I was wrong. The automatic copy constructor takes a reference, so no temporary object has to be made. The Counter object a is constructed via a reference to i. (It is still a separate object.)

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    48
    Quote Originally Posted by tabstop View Post
    Since we're not discussing pass by reference (to the post-increment function), the objection is irrelevant and immaterial.

    I have obviously got this mixed up, the function returns a reference, does this mean it just returns i ?

    Quote Originally Posted by tabstop View Post
    Because that's what "Counter a =" is. It's not an assigment, and it certainly doesn't magically make "a" a reference. If you wanted to make "a" a reference, you'd have to declare it as such, i.e. with
    Code:
    Counter &a =++i;

    Ok i get that, the return value being a reference is what is messing with me.

    Quote Originally Posted by tabstop View Post
    What you have is syntactic sugar for
    Code:
    Counter a(++i);
    Ok this looks a little more familiar, would this invoke the copy constructor? And so make a a direct copy of i after the function?

    I'm sorry its just a lot more confusing than what I have encountered so far.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MattJ812 View Post
    I have obviously got this mixed up, the function returns a reference, does this mean it just returns i ?
    It returns i, by reference. Theoretically, a reference to an object and an object are not the same type, but in the real world they are. The difference is copying, again:
    Code:
    Counter::Counter fn1();
    Counter::Counter &fn2();
    
    Counter Counter::Counter fn1() { return *this;}
    Counter& Counter::Counter fn2() { return *this;}
    
    .
    .
    .
    
    Counter a;
    a.fn1().SetItsVal(4); //the return from fn1 makes a copy, and the Set function affects the copy
    cout << a.GetItsVal() << endl;
    a.fn2().SetItsVal(4); //the return from fn2 _is_ a, so the Set function affects a
    cout << a.GetItsVal() << endl;

    And yes, "Counter a(another_Counter)" is a copy constructor, which creates "a" as a copy of another_Counter.

  8. #8
    Registered User
    Join Date
    Dec 2010
    Posts
    48
    Thanks that clears things up quite a bit. It seems some of my problems are arising from having to more or less unlearn a lot of what I learned using the game maker language.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  2. C++ FTP class won't work
    By lord mazdak in forum C++ Programming
    Replies: 8
    Last Post: 12-18-2005, 07:57 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM