Overriding the prefix/postfix operators
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Thread: Overriding the prefix/postfix operators

  1. #1
    Join Date
    Sep 2012
    Posts
    12

    Overriding the prefix/postfix operators

    I have an assignment which includes overriding the prefix and postfix operators, and my teacher has provided what the output from the program should be. I've written the code and it's nearly perfect, except for one tiny error I can't seem to get right.

    This is (most of) the code from the header--I left out a few of the parts that aren't relevant to my question:

    Code:
    using namespace std;
    #include<string>
    #include<iostream>
    class NumDays
    {
    private:
    	int hours;
    public:
    	NumDays() {hours = 0;}
    	NumDays(int);
    	NumDays(double);
    	void setHours(int);
    	void setDays(double);
    	int getHours();
    	double getDays();
    	operator double();
    	NumDays operator+(const NumDays&);
    	NumDays operator-(const NumDays&);
    	NumDays operator++(int);
    	NumDays operator--(int);
    	NumDays operator++();
    	NumDays operator--();
    };
    
    //******************************************************************
    NumDays::NumDays(int hparam)
    {
    	hours = hparam;
    }
    
    //******************************************************************
    NumDays::NumDays(double dparam)
    {
    	hours = dparam * 8.0;
    }
    
    //******************************************************************
    void NumDays::setHours(int h)
    {
    	h = getHours();
    }
    
    //******************************************************************
    void NumDays::setDays(double d)
    {
    	d = getDays();
    }
    
    //******************************************************************
    int NumDays::getHours()
    {
    	return(hours);
    }
    
    //******************************************************************
    double NumDays::getDays()
    {
    	return(hours / 8.0);
    }
    
    //**************************************************************
    NumDays NumDays::operator++(int)
    {
    	NumDays temp(hours);
    	hours++;
    	return temp;
    }
    
    //******************************************************************
    NumDays NumDays::operator--(int)
    {
    	NumDays temp(hours);
    	hours--;
    	return temp;
    }
    
    //******************************************************************
    NumDays NumDays::operator++()
    {
    	++hours;
    	return *this;
    }
    
    //******************************************************************
    NumDays NumDays::operator--()
    {
    	--hours;
    	return *this;
    }

    And here's main:

    Code:
    int main()
    {
        NumDays Employee1(20),
                Employee2(15);
        cout << "Employee1++: " << Employee1++.getHours() << endl;
        cout << "Employee1: " << Employee1.getHours() << endl;
        cout << "++Employee1: " << (++Employee1).getHours() << endl;
        cout << "Employee1: " << Employee1.getHours() << endl;
        cout << "Employee2--: " << Employee2--.getHours() << endl;
        cout << "Employee2: " << Employee2.getHours() << endl;
        cout << "(--Employee2)--: " << (--Employee2)--.getHours() << endl;
        cout << "Employee2: " << Employee2.getHours() << endl; //PROBLEM HERE
        cout << " days: " << Employee2.getDays() << endl; //AND HERE
    }
    The two problem lines are supposed to be outputting 12 and 1.5, respectively, but are instead showing 13 and 1.625. I know that hours is being changed to 12 at the end of the overriden prefix operation in the line above them, so I don't understand why it returns to 13 again. Can anyone help me understand what I need to change?

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,014

    Re: Overriding the prefix/postfix operators

    Quote Originally Posted by taymaxi View Post
    The two problem lines are supposed to be outputting 12 and 1.5, respectively, but are instead showing 13 and 1.625. I know that hours is being changed to 12 at the end of the overriden prefix operation in the line above them, so I don't understand why it returns to 13 again. Can anyone help me understand what I need to change?
    Not sure if this is actually the problem, but your prefix operators are returning a copy of the object. They should return a reference to the object.

    Further:
    - Don't put "using namespace std;" in a header file or before your include statements. It defeats the purpose of namespaces.
    - Your class is not const correct.
    - You should make the constructors that take a single argument explicit. Otherwise, you are defining an implicit conversion, which can cause unexpected behavior. When you have a function that takes a NumDays argument and you pass it an int or double, the argument will implicitly be converted. If you make the constructor explicit, you will get a compiler error instead.
    - Having two overloaded constructors that both take a numerical value but have different semantics is very bad design.
    - Cast operators are evil. They mess up the type system so bad that they are best avoided.

    FYI: overloaded functions/operators are functions with the same name, but different signature; an overridden function is a virtual function declared in a base class and defined in a derived class.
    Last edited by D_Drmmr; October 26th, 2012 at 04:38 PM.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    Sep 2012
    Posts
    12

    Re: Overriding the prefix/postfix operators

    Okay...to be honest, I'm not really sure what most of that means. Based on what you said, I made some changes so now the class definition reads:

    Code:
    #include<string>
    #include<iostream>
    using namespace std;
    class NumDays
    {
    private:
    	int hours;
    public:
    	NumDays() {hours = 0;}
    	NumDays(const int);
    	NumDays(const double);
    	void setHours(const int);
    	void setDays(const double);
    	const int getHours();
    	const double getDays();
    	operator double();
    	NumDays operator+(const NumDays&);
    	NumDays operator-(const NumDays&);
    	NumDays operator++(const int);
    	NumDays operator--(const int);
    	NumDays operator++();
    	NumDays operator--();
    };
    But I'm still having the same problem as before with it returning the wrong values--as you said, the issues you listed probably weren't related to that. So I still don't know what's wrong in that regard.


    Some of the other problems you listed are, I think, required by my instructor even if they are bad design. Maybe I'm wrong though. Here's the assignment's instructions:
    "Design a class called NumDays. The class's purpose is to store a value that represents a number of work hours and to return number of hours or number of working (8-hour) days. It must have only one private data element, hours, an int variable.
    Three constructors:
    -a default constructor that sets hours to 0
    -a constructor with an int parameter that sets hours to that parameter
    -a constructor with a double parameter (representing days) that sets hours to that parameter times 8.
    public member functions:
    -void setHours, void setDays, int getHours, and double getDays (with the obvious meanings, for example setDays(double d), would set the object's data element to d * 8).
    You also need to define five overloaded operators as member functions:
    -A type-conversion operator (double) that returns the number of days.
    - + Addition operator, returns a NumDays object holding the sum of the two added objects' hours.
    - - Subtraction operator
    -Postfix Increment and Decrement operators, x++ and x-- that add or subtract 1 (hour) from the object, and return the object's value before increment/decrement.
    -Prefix Increment and Decrement operators, ++x and --x that add or subtract 1 (hour) from the object and return a reference to the object.
    Differences between Prefix and Postfix operators:
    -The Postfix operator must return the value before it was incremented/decremented
    -The Prefix operator returns an lvalue, that is, it is declared NumDays& operator++(),
    -The Postfix operator returns an rvalue, and it has an extra dummy argument, that is, it is declared NumDays operator++(int).
    -The dummy argument is how the compiler distinguishes between the prefix and postfix operators, which otherwise would have the same signature.
    -The Prefix operators return *this (the compiler converts it to a reference return).
    -The Postfix operators need to create a local variable of type NumDays to hold the original value, before incrementing/decrementing, and return that
    Your file must compile and run with my testdays.cpp program, with no changes to testdays.cpp. The comments at the end show the expected output.
    You should store only hours (as an int) in your class. setDays must then convert days to hours, getDays hours to days.
    For full credit use const wherever appropriate"
    Last edited by taymaxi; October 26th, 2012 at 05:37 PM.

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,323

    Re: Overriding the prefix/postfix operators

    Quote Originally Posted by taymaxi
    But I'm still having the same problem as before with it returning the wrong values--as you said, the issues you listed probably weren't related to that.
    On the contrary, the issue that D_Drmmr spotted is precisely the problem. D_Drmmr was just being conservative in the initial assessment.

    Take a closer look at the statement just before your problem outputs:
    Code:
    cout << "(--Employee2)--: " << (--Employee2)--.getHours() << endl;
    Now, if you implement prefix operator-- to return by value, then (--Employee2) results in a copy of Employee2 that has the hours decremented. Thus, the subsequent postfix operator-- operates on that copy. This means that when you later print out the hours (and days) of Employee2, it only would have been decremented once, not twice.

    As such, you should declare:
    Code:
    	NumDays& operator++();
    	NumDays& operator--();
    and change the implementations accordingly.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Sep 2012
    Posts
    12

    Re: Overriding the prefix/postfix operators

    Quote Originally Posted by laserlight View Post
    As such, you should declare:
    Code:
    	NumDays& operator++();
    	NumDays& operator--();
    and change the implementations accordingly.
    Ahh, thank you! I actually saw a line in the instructions that specified this, and made the change myself along with a few other things, but didn't realize this was what made the difference. Thanks, now I understand what's going on.

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,014

    Re: Overriding the prefix/postfix operators

    Quote Originally Posted by taymaxi View Post
    Okay...to be honest, I'm not really sure what most of that means.
    Well that's what learning is all about. However, a bit of googling will often get you a long way. E.g. C++ explicit constructor
    Quote Originally Posted by taymaxi View Post
    Some of the other problems you listed are, I think, required by my instructor even if they are bad design. Maybe I'm wrong though.
    Well, even if your instructor requires you to do things that are considered bad programming, you can still learn them the right way.
    Just think about how you would use the class that you've implemented in a program.
    However, your teacher did implicitly refer to one of the points I made.
    Quote Originally Posted by taymaxi View Post
    For full credit use const wherever appropriate"
    That is called "const correctness".
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center