13.6 — 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

13.7 -- Overloading the comparison operators
13.5 -- Overloading operators using member functions

106 comments to 13.6 — Overloading unary operators +, -, and !

  • Anastasia

    Shouldn't we return by reference in the quiz? I mean we know that `this` exists outside of the function scope, why copy it?

    And a little inconsistency in the code examples: the getters in the Point class are not const for some reason.

    • Alex

      Good question. I added a note about why this was done to the answer.

      Fixed the issue with the missing consts.

      • Anastasia

        I see. I assume we could also overload `operator+()` function for const and non-const members

        if the copying would result too expensive (not the case here).

        Thank you!

        edit: by "members" I meant "class instances" of course :/

  • mmp52

    Hi there!
    This tickles my mind, how can unary operators like operator- be applied using member functions and why does compiler not give an error when we call:

    In the previous lesson, overloading operators using member functions required followings to be satisfied:  
      *The overloaded operator must be added as a member function of the left operand.
      *The left operand becomes the implicit *this object
    When you call

    the operand (object itself) is in the right

  • cdecde57

    Hello! I think that I understand the main idea of this lesson great. I made a program trying to fit in what I have learned so far and it has been great! I am posting it here for any feedback. By the way, I am just curious about the overloading of the operator+ in this lesson. I understand like in the previous you can fuse 2 strings together and make something like this,

    string1 = "Hello,"
    string2 = " World!"

    overload+ the 2 strings = "Hello, World!"

    But I am confused about the quiz's general like idea. Anyways that would be great if I could get more insight on the quiz. Anyways this is my program I made any feedback would be great.

    • - Initialize your variables with brace initializers.
      - Limit your lines to 80 characters in length for better readability.
      - Line 10-28 should be `const`.
      - Use single quotation marks for characters.
      - Inconsistent and mixed name style.

      • cdecde57

        Thank you! Will do. Anyways I am wondering if you could maybe describe the unary + a little bit to me. I am having a hard time understanding its purpose or what it actually does so any help would be great.

        • The unary+ is rarely used, because usually `n == +n`.
          You could use it for custom transformations, eg. capitalizing strings.

  • Jon

    Hello, just curious, what are some real-life examples of when the unary + operator is useful? Thanks!

    • Alex

      Unary + is really there just for symmetry with unary -. Probably the most useful thing I can think of is for text alignment purposes, like this:

  • Jack

    Thanks nascardriver. the unary + was probably not a good example as it's redundant, but the same happens with the unary - operator. I can't say I fully understand what's going on but I'll persevere and see if I can figure it out.

    • If you want to create a new object, you'll have to construct a new one.

  • Jack

    overloading operators.
    I thought I'd got this, until I started playing with it (ie seeing what broke it).

    It appears that invoking an overloaded operator initiates a call to the constructor, so if anything happens in the constructor body it happens every time the overloaded operator is called. This seems a problematical unforeseen consequence. Prog  below written to show this. what an I missing?

    this outputs:

    in constructor 'this' = 0x6efef4
    a pu  is worth 9 ningis
    a pu  is worth 9 ningis

    in overload func 'this' = 0x6efef4
    in constructor 'this' = 0x6efebc
    a pu of debt is worth 10 ningis
    in overload func 'this' = 0x6efef4
    in constructor 'this' = 0x6efebc
    a pu of debt is worth 10 ningis

    • Hi!

      * 34, 43: Initialize your variables with uniform initialization. You used direct initialization.
      * Line 3, 30: Limit your lines to 80 characters in length for better readability on small displays.

      You're calling @Ningis::Ningis in line 34. Since you know that members are unaffected by the unary +, you can just return a reference to the object it was called on.

      If you you don't want to return the same object, then there's no way around constructing a new Ningis.
      This problem is unrelated to operators. The same would happen to a regular function. Operators that don't need to create a copy don't need to call a constructor.

  • Yusuf Sönmez

    Hello. I didn't understand why do we need it. And when I change the operator from (-) to (+) anything is not change.Why? Can you help me please..

  • Gaurav Arya

    Hi All,

    I tried to make a unary operator example but with complex numbers. It seems to be working but I would appreciate your feedback/comments.



    • Hi Gaurav!

      * Line 8 is unnecessary, you can initialize @_real and @_im at their declaration.
      * Identifier names starting with an underscore are reserved. A common convention for member variables is "m_*", so "m_real".
      * Initialize your variables with uniform initialization
      * @ComplexNumber(int real, int im) should use a member initializer list
      * @ComplexNumber::operator- can be reduced to

  • 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]