9.5 — Overloading unary operators +, -, and !

Overloading unary operators

Unlike the operators you’ve seen so far, the positive (+), negative (-) and logical not (!) operators all are unary operators, which means they only operate on one operand. Because they only operate on the object they are applied to, typically unary operator overloads are implemented as member functions. All three operands are implemented in an identical manner.

Let’s take a look at how we’d implement operator- on the Cents class we used in a previous example:

This should be straightforward. Our overloaded negative operator (-) is a unary operator implemented as a member function, so it takes no parameters (it operates on the *this object). It returns a Cents object that is the negation of the original Cents value. Because operator- does not modify the Cents object, we can (and should) make it a const function (so it can be called on const Cents objects).

Note that there’s no confusion between the negative operator- and the minus operator- since they have a different number of parameters.

Here’s another example. The ! operator is the logical negation operator -- if an expression evaluates to “true”, operator! will return false, and vice-versa. We commonly see this applied to boolean variables to test whether they are true or not:

For integers, 0 evaluates to false, and anything else to true, so operator! as applied to integers will return true for an integer value of 0 and false otherwise.

Extending the concept, we can say that operator! should evaluate to true if the state of the object is “false”, “zero”, or whatever the default initialization state is.

The following example shows an overload of both operator- and operator! for a user-defined Point class:

The overloaded operator! for this class returns the boolean value “true” if the Point is set to the default value at coordinate (0.0, 0.0, 0.0). Thus, the above code produces the result:

point is set at the origin.

Quiz time

1) Implement overloaded operator+ for the Point class.

Show Solution

9.6 -- Overloading the comparison operators
9.4 -- Overloading operators using member functions

62 comments to 9.5 — Overloading unary operators +, -, and !

  • Hi,

    The total solution including the overloaded unary + operator is:

    but isn't this rather pointless as it will just return the same as was input anyway?

  • Hi Alex,

    For the '+' operator, are we trying to return the positive version of the object?
    For example:

    Wouldn't return (1,1,1). Instead it would return (-1,-1,-1). Is this the goal for the unary '+' operator?

    If we wanted to return the positive version for a negative object, then I would suggest the '+' operator overloaded function be written as below:

    We return the absolute value of the operands, so they are always positive.

    Note: In the above code, if we do the following

    Then we would get a positive output, i.e (1,1,1).
    My question is : What are we trying to achieve with the '+' operand here?

    • Hi Kumar!

      @operator+ should work as it does with numbers, that is

      So all you have to do is return an unmodified copy of the point.

      Comment to your @operator+ suggestion (It's not what @operator+ should do, but that aside)

      • Okay. That makes sense. I was just confused about what the operator '+' is intended for in this case.
        Thank you for your suggestions.
        I would use uniform initialization, but the

        seems clearer for me, to know that the function is returning an anonymous object.
        Are there any advantages to using uniform initialization as you have mentioned, over the above code? Please do let me know.

        • > seems clearer for me
          You can still use uniform initialization then

          Omitting the class name is a voluntary feature of uniform initialization when returning values.

          > advantages
          Prevents possibly unwanted narrowing casts (Lesson 2.1)

  • Winston Lai

    Hi, in the code below, when you return Cents(-m_cents) when (-) is applied on object nickle, wouldn't that modify the members of nickle since you called the constructor Cents again and pass in (-m_cents) as your integer parameter and caused private member m_cents to be modified for the object?

  • Ran

    I am not sure why the following code not work. The operator+ seems to
    be a function without any input because the complier tells me that
    "too many parameters for this operation function".

    Point operator+ (const Point &a, const Point &b);

    Point Point::operator+ (const Point &a, const Point &b)
        return Point(a.getX + b.getX, a.getY +b.getY, a.getZ + b.getZ);

    • nascardriver

      Hi Ran!

      operator+ excepts exactly 0 or 1 arguments.

      Here's an example:


    • Matt

      Hello Ran!

      It seems you might be confusing unary plus with binary addition.

      From lesson 3.2:

      Unary arithmetic operators

      There are two unary arithmetic operators, plus (+), and minus (-). If you remember, unary operators are operators that only take one operand.

      Operator        Symbol  Form    Operation
      Unary plus      +       +x      Value of x

      The unary plus operator returns the value of the operand. In other words, +5 = 5, and +x = x. Generally you won’t need to use this operator since it’s redundant. It was added largely to provide symmetry with the unary minus operator.

      Binary arithmetic operators

      Operator        Symbol  Form    Operation
      Addition        +       x + y   x plus y

      The addition, subtraction, and multiplication operators work just like they do in real life, with no caveats.

  • Dani

    Hi Alex,
    I have a question regarding the second solution to the quiz.
    When you're returning *this, is the dereference of this the same instance of Point as the one you use the operator on?
    And if so, how good practice is it to have operator- to return a new instance of point but operator+ returning the same instance?

    • Alex

      > When you’re returning *this, is the dereference of this the same instance of Point as the one you use the operator on?


      > And if so, how good practice is it to have operator- to return a new instance of point but operator+ returning the same instance?

      Both plus and minus return a _new_ instance of point. This is because the return type is by value, not by reference. Therefore, the value returned is a copy of whatever is returned.

      Thus, when we return *this, we're actually returning a copy of *this, not the actual *this.

  • John Halfyard

    Very minor typo

    "it's" should equal "its"

  • shraa

    Hi Alex,

    I am trying some basic codes for operator overloading. This is how i have defined my function:

    Test* Test::operator+(Test &obj)
        Test temp;
        cout<< "address in this variable is :" << this<<endl;
        cout<< "address of object temp is "<<&temp<<endl;
        return &temp;

    Here i am trying to return address of object.( hope i have done it correctly). My question is, In main(), how can I take this address and do addition on my class objects..
    i was doing it this way:

    int main()
        Test t1(3,4);
        cout<< "address of object t1 is "<<&t1<<endl;
        Test t2(7,9);
        cout<<"address of object t2 is "<<&t2<<endl;
        Test *res=new Test();
    return 0;

    I am sure something is wrong and I am not getting that. here is what I receive when run:
    address of object t1 is 0x7ffc2d04a7a0
    address of object t2 is 0x7ffc2d04a7b0                                                                                                                        
    Segmentation fault

    Can you please suggest how to solve this? and why I am getting this error?

    • Venkat Reddy

      Here you are taking a local object(Test temp;).Scope of this object ends once the controller comes out of the function and that address (ie., &temp) will be invalid.
      when you are calling "res->Display();", res (ie.,&temp) address is accessed which is invalid and eventually it leads to Segmentation fault.
      You can return object itself instead of returning obj address and assign this result to another object in main().

  • Abdulla

    Hi Alex .. the last example of unary ! . I would think that ! Doesn't play it's role -it's role which is mintioned above the example - since it is only used as overloaded operator ?  I mean the overloaded operator is just a function. And u have to use operator (!) Within a function .. did i misunderstand something?

    • Alex

      Not sure what you mean. In main(), the (!point) part of the if conditional calls Point::operator!, which returns true, so the if statement executes.

  • Shouldn't this:

    Be like this? :

    I mean, if there is a negative value, return it as positive, the opposite of the negation overload?

    • Alex

      If you run this program:

      You'll see that the answer is still -5, not 5. Unary operator+ does not make negative numbers positive. It simply returns the value of its operand.

      And if it just returns the value of its operand, then it's essentially superfluous in this context. That's why I didn't include it in Point's operator+ (it doesn't do anything).

      FWIW, if you want to make a negative number positive, you have to do something like this: ((x > 0) ? x : -x)

  • Mohammad

    Hello, im not sure what the const is for and why is it at the end?

  • Liang

    In the following statements,
    "Our overloaded negative operator (-) is a unary operator implemented as a member function, so it takes no parameters (it operates on the *this object). It returns a Cents value that is the negation of the original Cents (by value). ..."
    do you mean
    It returns a new Cents object with the value that is the negation of the original Cents value.



  • Ehsan

    Hi, would this be valid/recommended?

    or alternatively


  • Eelco

    Hi Alex,

    Thanks very much for this tutorial! I have a question regarding this paragraph's quiz:

    You state that the obvious solution is:

    But I can't really figure out why the minus signs are put before m_y and m_z. In my own version, I didn't use these. Is this perhaps a copy-paste error, or am I missing the point?

    Your help is much appreciated!

    Kind regards,


  • Jens

    Hey Alex. I have two questions:
    1) In the first example, where you overloaded operator-, you used you overloaded operator like this:

    Doesn´t that example just use the normal operator-? I mean, getCents returns a double and it just seems as though the operator- just uses that double to perform the built in operator- function. I took away the whole overloaded operator and it still works.

    2)In the quiz your answer is:

    Are the -m_y and -m_z just typos or am I missing something?

    Sorry if these questions are stupid, but it always bugs me when I´m left wondering about something, so I thought I´d make a question.

    • Alex

      1) Hah, you found an error. It was using getCents to return a double and then applying operator- to the double. I've updated the example so it executes like I intended:

      Now operator- will be applied to the Cents object first, and then getCents() will be called on the result.

      In this particular example, it ends up the same result either way.

      2) The -m_y and -m_z were copy/paste errors from the overloaded operator-. I've fixed them. Thanks for pointing that out.


    Hey Alex,
    I have found where the problem is, Because it's a anonymous-objects, so it's a rvalue, you must be refer to by value or const reference.. Yeah, Thanks !!


    #include <iostream>

    class Point
        double m_x, m_y, m_z;

        Point(double x=0.0, double y=0.0, double z=0.0):
            m_x(x), m_y(y), m_z(z)


            Point operator- () const;

            Point operator+ () const;

            // friend std::ostream& operator<< (std::ostream& out, const Point& point);
            friend std::ostream& operator<< (std::ostream& out, Point& point);

            double getX() const { return m_x; }
            double getY() const { return m_y; }
            double getZ() const { return m_z; }

    Point Point::operator- () const
        return Point(-m_x, -m_y, -m_z);

    Point Point::operator+ () const
        return Point(m_x, m_y, m_z);

    // friend std::ostream& operator<< (std::ostream& out, const Point& point);
    std::ostream& operator<< (std::ostream& out, Point& point)
        out << point.getX() << " " << point.getY() << " " << point.getZ();
        return out;

    int main()
        Point point(2.3, -4.6, 2.5);

        std::cout << point << '\n'; // It works

        std::cout << +point << '\n'; // It doesn’t work at all. I am confused about that.
        std::cout << -point << '\n';

        Point point2 = +point;
        std::cout << point2 << 'n'; // It also works

        return 0;

    Hey, Alex. I have a few questions.
    ① Does +point or -point a const Point object?
    ② But when i change the 2th parameter of the << overloading operator function into "const Point& point",
       it works,Why??
    I thinks it’s a rvalue, right?
    Thanks a lot:)

    • Alex

      1) No, it can work on a const or non-const object (you can always make a non-const object const, but not the other way around).
      2) The problem is you're trying to pass an anonymous object (the Point returned by operator+) by non-const reference to operator<<. You can't do that. As you've already noted, making the parameter const addresses the issue (and it really should be const anyway, since operator<< doesn't modify the parameter).

  • phanhoang

    "Point operator- () const;"
    hey, i confused with that line, what "const" is meant??
    thanks you

    • Alex

      I means the function itself is const, and promises not to modify the internal state of the object it's working on. This allows it to be called on const variables.

      • phanhoang17

        Oh, thanks: )))))

      • AKG

        Hey Alex, as i understand 'operator-' modifies the member of class. If +ve value is converted to -ve value it will be stored in 2's complement , right? So the stored value gets changed internally, though when we print it its value is same except sign change.

        • Alex

          Yes, if you convert a positive value to a negative value, the binary representation will change. However, the variable's type does not change. For signed integers, the value will always be stored in two's complement (positive numbers won't have the sign bit set, negative numbers will).

          • AKG

            Yes Alex, I agree, but my question is what about the understanding of statement

            "Point operator- () const;"
            "It means the function itself is const, and promises not to modify the internal state of the object it’s working on. This allows it to be called on const variables"

            So here Operator- () modifies internal state of object, right ? But const key says it will not modify the internal state of object.

            • Shiva

              No it doesn't. If you look closely at the implementation of operator-, you'll see that all it does is create an anonymous object of Point class and return it to the caller. It doesn't modify the parent object's members; it accesses them only to call the Point() constructor with [the negatives of] those values.

              Hope that helps. 🙂

            • Alex

              > So here Operator- () modifies internal state of object, right ?

              Oh, no, operator- doesn't modify (change) the internal state of the object. It returns a new object that is the negative/inverse version of the object being operated upon.

  • Mr D

    Thanks for the explanation, i get it!

  • Mr D

    Hi Alex,

    Something is confusing me!:

    With overloading the "-" operator, you use:

    But with overloading the "!" op', you use:

    But why isn't it:


    • Alex

      Generally when we overload operators, we try and keep them as close to the "intent" of the original operator as possible. So while you could make operator- multiply each of the dimensions in your Point by 2, that would be rather confusing, because we wouldn't expect operator- to do that.

      Now let's consider how operator! (logical NOT) works with normal variables. For a normal boolean value, it returns true when the boolean is false (0), and false when the boolean is true (1). For an integer, it returns true when the integer is 0, and false otherwise. We could generalize this to say that operator! returns true whenever our input value is a zero/null value, and false otherwise.

      What's the zero value for a Point? Point(0.0, 0.0, 0.0) is the closest thing. So for consistency, it makes sense that our operator! return true when the Point is the zero Point (0.0, 0.0, 0.0) and false otherwise.

      If operator! did return a Point, what values would you expect it to have if you gave it Point(1.0, 2.0, 3.0) as input?

  • C++ newbie

    Hey there, I just want to say that this chapter has been an excellent read, and the tutorial so far has been a blast.  I came in with no prior experience and now I would consider myself sufficient in the language that I could write that I know it on my CV.  Thanks again for setting this website up.

  • Janez

    Is it ok to compare floating-point values like that (dX == 0.0)?

    • Alex

      Normally, no. However, I'm doing so here for simplicity.

      • João Gueifão

        Hi Alex, perhaps a one-sentence comment on that perhaps would be a good idea, so to alert new programmers on that fact.... or you could change the data type to plain integers.

        (I am loving this tutorial!)

        • Alex

          Actually, in this case, it's probably okay, since we're ONLY testing to see whether the value is 0.0 or not. All floating point numbers should be able to represent 0.0 precisely if explicitly assigned.

  • Shaun

    Is there an operator I can use to overload the usual if() effect? E.g.,

    What would happen in this case? Would C++ call the ! operator and reverse the result? Or is there another way to provide a boolean operator?

    • I think you could do this via overloading typecasts. If you provide an overloaded boolean conversion operator for your point, then I think the above example would work. This is covered in lesson 9.10.

      However, personally I wouldn't recommend implementing it this way. The conversion from point to boolean isn't very intuitive. I think this is better implemented as a member function that returns a boolean result -- in this way, your code will be more self-documenting. eg:

      • Adrian

        If I may add a remark: In my opinion Shaun is quite right … If you decide to have an operator!() to check whether a point is non-zero, then it might also be intuitive to have a means of checking the opposite condition.

        But considering the technical point of view, the usual way to do this would be a typecast to void *, even if this looks strange at first sight. This is because a pointer-to-void is perfectly legal as the expression of an if-statement, but it will not be automatically converted to many other things. As a consequence, typing errors are less likely to bite you, because they will produce compiler errors more often.

        A typical example are all std::ios objects, which provide a typecasting operator void *() (and the opposite operator!()) in order to check their state. Consider the stereotypical example, assuming n is an int:

        If std::cin had a conversion operator to bool, the second line would in fact compile, but it would certainly not do what you intended.

        • Gurjinder

          There is a problem with the typecast to void* approach. Because the object can be typecast to a void*, delete operator can be invoked on the object now (though the object is on stack):

          This can be disastrous!!!

      • Darren

        Using the ! operator in this way looks counter-intuitive to me. Writing something like

        to check if the point is at the origin makes it seem like we are saying the origin is not a point. But it is a point just with a special set of values in reference to some coordinate system. Having a descriptive member function to check the location of the point makes far more sense in my mind.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]