Overloading unary operators using pointers

This is a discussion on Overloading unary operators using pointers within the C++ Programming forums, part of the General Programming Boards category; Hi Please take a look at this non-compilable example: Code: #include <iostream.h> class test{ public: int a; friend operator++(test *b); ...

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    140

    Overloading unary operators using pointers

    Hi

    Please take a look at this non-compilable example:

    Code:
    #include <iostream.h>
    
    class test{
    public:
    	int a;
    	friend operator++(test *b);
    };
    
    operator++(test *b)
    {
    	b->a=b->a+1;
    }
    
    int main()
    {
    	test asd;
    	asd.a=1;
            &asd++;
    
    	return 0;
    }
    This will only compile if I replace the pointer *b with a reference. In my book it says that the reason why that is the case is because "&asd++ is inherently ambigous", but explains it no further.

    What does the author mean by that?

    Best,
    Niles.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    That code should not compile even if you "replace the pointer *b with a reference". The parameter for postfix operator++ should be of type int. Then, you failed to declare the operator++ with a return type, and you made it a non-member friend function, but failed to provide it with a parameter by which the object can be passed (i.e., the parameter before the int parameter).

    By the way, <iostream.h> is pre-standard. You do not need it here, but you should otherwise use <iostream>.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    laserlight: note that this is an attempt to overload it as a free function.

    Niels: You can't overload operators for pointers, because those are built-in types. Operator++ is already defined for all pointers.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by anon
    laserlight: note that this is an attempt to overload it as a free function.
    Yes, so...?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    1) "The parameter for postfix operator++ should be of type int." - Sorry, I don't know what you mean here.

    2) "Then, you failed to declare the operator++ with a return type" - I don't believe that is necessary in my case. I am using a pointer, so why return anything?

    3) "and you made it a non-member friend function, but failed to provide it with a parameter by which the object can be passed (i.e., the parameter before the int parameter)." - Sorry, I don't know what you mean here either.

    4) "By the way, <iostream.h> is pre-standard. You do not need it here, but you should otherwise use <iostream>.": Noted, thanks.


    This works:

    Code:
    #include <iostream>
    
    class test{
    public:
    	int a;
    	friend void operator++(test &b);
    };
    
    
    void operator++(test &b)
    {
    	(b.a)++;
    }
    
    int main()
    {
    	test asd;
    	asd.a=1;
    	asd++;
    
    	return 0;
    }

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by Niels_M
    1) "The parameter for postfix operator++ should be of type int." - Sorry, I don't know what you mean here.
    Quote Originally Posted by Niels_M
    3) "and you made it a non-member friend function, but failed to provide it with a parameter by which the object can be passed (i.e., the parameter before the int parameter)." - Sorry, I don't know what you mean here either.
    That is, if you want to overload postfix operator++, it should either be a member function and have a dummy int parameter, or be a non-member function and have two parameters, the second of which should be the dummy int parameter. Without this int parameter, you would be overloading it as a prefix operator++.

    Quote Originally Posted by Niels_M
    2) "Then, you failed to declare the operator++ with a return type" - I don't believe that is necessary in my case. I am using a pointer, so why return anything?
    Language syntax. There are exceptions, e.g., constructors, destructors and conversion functions are not declared with a return type (though the return type is kind of explicitly stated for the conversion function anyway), but operator++ is not such a case.

    Quote Originally Posted by Niels_M
    This works:
    Not likely, unless there is some kind of language extension at work. If you change asd++; to ++asd; then it should work (or at least it should compile). Rather, if you want to overload for postfix operator++, you should write:
    Code:
    friend void operator++(test &b, int);
    and
    Code:
    void operator++(test &b, int)
    {
    By the way, is anon's guess correct? That is, are you trying to overload postfix operator++ for a pointer type? If so, then your attempt is as futile as anon stated.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    Thanks for answers to 1, 2 and 3.

    If I have understood anon correctly, that is not what I am asking. What I am trying to do is to understand why I cannot do the following:

    Code:
    test_class operator++(test_class *ptr1)
    {
       ptr1->var_int++;
    }
    but I have to use this instead:

    Code:
    test_class operator++(test_class &ptr1)
    {
       ptr1.var_int++;
    }
    For now, let us not care about that test_class is, only that it contains var_int as an integer-variable. As I said before, the author of my book says that the reason the first example does not work is becayse "&test_class_object++ is inherently ambigious".

    I don't know what he means by that.


    EDIT: I hope you see this before replying, but postfix, prefix and all that is not what I am asking. Only why I cannot access test_class_object using a pointer to it in operator++, but why is has to be a reference.
    Last edited by Niels_M; 09-03-2010 at 01:11 PM.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Yes, so...?
    Sorry, didn't properly read your reply.

    If I have understood anon correctly, that is not what I am asking. What I am trying to do is to understand why I cannot do the following
    Just as I said. You can overload operators for class-types, and can't change the way operators work for built-in types. For pointers, ++ advances the pointer by the size of the object.

    For overloaded operators, (all) operands cannot be pointers.

    The next thing you might want to try to do is:

    Code:
    int operator+(int a, int b) { return a - b; }
    No idea why the author says anything about inherent ambiguity.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Let us consider the explicit form for calling prefix operator++. That is, given an object x of some class type, this:
    Code:
    ++x;
    can be written as:
    Code:
    x.operator++();
    or:
    Code:
    operator++(x);
    Now, let us consider the explicit form for calling postfix operator++. That is, given an object y of some class type, this:
    Code:
    y++;
    can be written as:
    Code:
    y.operator++(0);
    or:
    Code:
    operator++(y, 0);
    where 0 can be replaced by some other integer value in the range of int.

    So, a non-member function with this declaration:
    Code:
    test_class operator++(test_class *ptr1);
    is a non-member function that overloads prefix operator++ to return a test_class object, with a pointer as the argument. This is simply not allowed, since operator++, in both prefix and postfix forms, already exists for pointers.

    Quote Originally Posted by Niels_M
    As I said before, the author of my book says that the reason the first example does not work is becayse "&test_class_object++ is inherently ambigious".

    I don't know what he means by that.
    I think that the author is mistaken. The first example does not work because one cannot overload operator++ for a pointer.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    But guys, we are not overloading ++ for a pointer, but for objects of test_class. The only thing we are doing is using a pointer as a way of identifying the test_class_object.

    But OK -- let us assume I accept your explanations, and use e.g. a reference instead (as in my example). Then I have a non-member function that overloads the prefix operator++ to return a test_class object, with a reference as the argument. This should mean that I cannot use a reference in any other prefix operator++ function for any other class. But this is not the case.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    Quote Originally Posted by Niels_M
    But guys, we are not overloading ++ for a pointer, but for objects of test_class.
    Right.

    Quote Originally Posted by Niels_M
    The only thing we are doing is using a pointer as a way of identifying the test_class_object.
    According to the language rules, you cannot do this.

    Quote Originally Posted by Niels_M
    But OK -- let us assume I accept your explanations, and use e.g. a reference instead (as in my example). Then I have a non-member function that overloads the prefix operator++ to return a test_class object, with a reference as the argument. This should mean that I cannot use a reference in any other prefix operator++ function for any other class. But this is not the case.
    In other words, your claim that you "cannot use a reference in any other prefix operator++ function for any other class" is false.

    EDIT:
    Think about it: why should it be true? Why should having a reference parameter of type T1 for a function foo mean that you cannot overload function foo to have a reference parameter of another type T2, in general?
    Last edited by laserlight; 09-03-2010 at 01:57 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    But guys, we are not overloading ++ for a pointer, but for objects of test_class. The only thing we are doing is using a pointer as a way of identifying the test_class_object.
    The argument to operator++ (as a non-member function) is the operand.

    Code:
    test operator++(test *b)
    {
    	b->a=b->a+1;
            return *b;
    }
    If this was allowed, the usage would look like
    Code:
    test* p = new test;
    ++p;  //would not increment the pointer!?
    I don't understand the second part of the question. The proper way to overload pre- and postfix increments (as non-member functions) looks like this:

    Code:
    X& operator++(X& x) //++x
    {
          x.increment();  //whatever
          return x;
    }
    
    X operator++(X& x, int)  //x++
    {
          X before_increment = x;
          ++x;
          return before_increment;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  13. #13
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    "The argument to operator++ (as a non-member function) is the operand." - In the case when overloading an operator using a member function, then the argument is not the operand?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,647
    A unary operator overloaded as a member would have no parameters; its operand is the current object (*this). Postfix operator++ and operator-- are exceptions in that they do have a parameter when overloaded as a member, but this parameter is just a dummy int parameter to differentiate them from prefix operator++ and operator-- respectively.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Aug 2009
    Posts
    140
    I was thinking in more general terms, i.e. also binary operators. I mean, lets say I have

    Code:
    class dummy_class{
    public:
       int a;
       void operator+(dummy_class* test);
    }
    This is totally legal, but it would not be legal if operator+ was a non-member function. My post #13 is basically just trying to figure out why (I have read about the this-pointer now).

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 01-22-2002, 11:25 AM
  2. About overloading operators.
    By Dual-Catfish in forum C++ Programming
    Replies: 2
    Last Post: 12-29-2001, 06:12 PM
  3. Overloading operators...
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 11-21-2001, 07:24 PM
  4. Overloading Operators
    By Raven Arkadon in forum C++ Programming
    Replies: 1
    Last Post: 10-24-2001, 10:24 AM
  5. Overloading Operators
    By Strahan in forum C++ Programming
    Replies: 4
    Last Post: 09-07-2001, 11:39 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21