Thread: Error when overloading...

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    36

    Error when overloading...

    I keep receiving this error when trying to overload the * operator to multiply an object by an integer:

    " error C2677: binary '*' : no global operator defined which takes type 'class percent' (or there is no acceptable conversion)"

    Here is my code:
    Code:
    #include <iostream>
    
    class percent
    {
    private:
        int whole;
    	int decimal;
    public:
    	percent();
        percent(float z);
        int getwhole(void);
    	int getdecimal(void);
    	void setwhole(int z);
    	void setdecimal(int z);
    	float getpercent(void) const;
        void percent::setpercent(float z);
    	void print(void);
    
    	percent operator+(const percent& z) const;  //e = f + g;
        percent operator-(const percent& z) const;  //e = f - g;
        percent operator*(const percent& z) const;  //e = f * g;
        percent operator/(const percent& z) const;  //e = f / g;
        percent operator*(int z) const;             //c = a * f;
        friend std::ostream& operator<<(std::ostream& y, const percent& z);
    	friend std::istream& operator>>(std::istream& y, percent& z);
    
        
        
      
    //c = a / f;
    
    //c = c * f;
    //c = c / f;
    
    //c = f * a;
    //c = a / f;
    
    //c = f * c;
    //c = f / c;
    
    //e = f;
    
    //e++;
    //++e;
    //e--;
    //--e;
    
    //if (e == f)
    
    //if (e != f)
    
    //if (e > f)
    
    //if (e >= f)
    
    //if (e < f)
    
    //if (e <= f)
    
    //cin >> e;
    
    //cout << e;
    
    };
    
    using namespace std;
    
    percent::percent()
    {
    	whole = 0;
    	decimal = 0;
    }
    percent::percent(float z)
    {
    	whole = z;
    	decimal = (z - whole) * 100;
    }
    int percent::getwhole(void)
    {
    	return whole;
    }
    int percent::getdecimal(void)
    {
    	return decimal;
    }
    void percent::setwhole(int z)
    {
    	whole = z;
    }
    void percent::setdecimal(int z)
    {
    	while (z >= 100)
    	{
    		z = z - 100;
    		whole++;
    	}
    	decimal = z;
    }
    float percent::getpercent(void) const
    {
        return whole + (decimal) / (100.0);
    }
    void percent::setpercent(float z)
    {
    	whole = z;
    	decimal = (z - whole) * 100;
    }
    void percent::print(void)
    {
    	cout << "Whole: " << whole << endl;
    	cout << "Decimal " << decimal << endl;
    }
    percent percent::operator+(const percent& z) const
    {
    	percent temp;
    	temp.setwhole(whole + z.whole);
    	temp.setdecimal(decimal + z.decimal);
    
    	return temp;
    }
    percent percent::operator-(const percent& z) const
    {
    	float a, b, c;
    	percent temp;
    	
    	a = getpercent();
    	b = z.getpercent();
    
    	c = a - b;
    
    	temp.setpercent(c);
    
    	return temp;
    }
    percent percent::operator*(const percent& z) const
    {
    	float a, b, c;
    	percent temp;
    	
    	a = getpercent();
    	b = z.getpercent();
    
    	c = a * b;
    
    	temp.setpercent(c);
    
    	return temp;
    }
    percent percent::operator/(const percent& z) const
    {
        float a, b, c;
    	percent temp;
    	
    	a = getpercent();
    	b = z.getpercent();
    
    	c = a / b;
    
    	temp.setpercent(c);
    
    	return temp;
    }
    percent percent::operator*(int z) const
    {
        float a, b;
    	percent temp;
    	
    	a = getpercent();
    
    	b = a * z;
    
    	temp.setpercent(b);
    
    	return temp;
    }
    
    
    ostream& operator<<(ostream& y, const percent& z)
    {
    	y << z.whole << "." << z.decimal << "%";
    
    	return y;
    };
    
    istream& operator>>(istream& y, percent& z)
    {
    	float temp;
    	y >> temp;
    	z.setpercent(temp);
    
    	return y;
    };
    
    int main()
    {
        int a = 0, b = 0;
        float c = 0, d = 0;
        percent f(6);
    
    	percent e(20);
    	percent g(5);
    	//e.print();
    
    	c = a * f;
    
    	cout << c << endl;
    
    
    
    	return 0;
    }
    Any ideas on how to fix?

    Thanks.

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Provide a global operator*() of the following form;
    Code:
    percent operator*(int, const percent &);
    This function may be implemented as a friend of your class if you wish. This is the version that will be called (if it exists) at your line "c = a*f;", as a is an int.

    The alternative is to change the line "c = a*f;" into "c = f*a;" as that form will call your percent:perator*(int) that you have already supplied.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Any ideas on how to fix?
    When you overload operators, you're also implicitly defining the order the terms will appear. This line:

    c = a * f;

    says to call the multiplication function on 'a', and send 'f' as an argument to the function. In other words, you are trying to call a multiplication function defined for the int 'a' that has 'f' as a parameter. There is no multiplication function that ints can call that takes an 'f' object--after all how could the inventors of C++ ever anticipate that you would define a class called percent.

    On the other hand, this function:

    percent operator*(int z) const;

    allows you to do this:

    f * a

    where 'f' is a percent object and a is an int. It says to call the operator*() function defined for f objects and send it the argument 'a'. Since you defined a function in your percent class to do just that, then it will work.
    Last edited by 7stud; 10-16-2005 at 12:30 AM.

  4. #4
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    What would the function need to look like to be able to do c = a * f?

  5. #5
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    percent operator* (int, const percent&);

    which could easily be defined using your already established operators and constructors

    Edit: note that it would be a non member function and if you define it in terms of other operators and such it doesn't even have to be a friend

  6. #6
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    I am a little confused.
    percent operator* (int, const percent&);

    Why isn't there a variable name after int and percent&?
    I understand you don't have to have any, but how would you manipulate anything in the definition without variable names?
    I don't quite understand the function defininition, either. Everything I try to write causes error messages.

    Thanks for your help.

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I gave a prototype not a header. I'm feeling a little nice so here:
    Code:
    percent operator* (int k, const percent& p)
    {
      return p * k;
    }
    Btw as a general rule of thumb you define the +=, -=, *=, /=, %=, for the item and then use the copy constructor and the approiate operator to define binary +, -, *, /, %

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    This is where operator overloading gets a little tricky. As I explained above, if you do this:

    c = a * f;

    you are calling the operator*() function on the int a. Therefore, the operator*() function cannot be a member function of your class. Member functions of a class are called by objects of the class, and 'a' is not an object of your class. Therefore, you cannot use the format:

    percent operator*(int z) const;

    That implies you are calling operator*() on a user defined class, and an int isn't a user defined class. So, you have to define your operator*() function as a regular function outside of any class. As it turns out, that requires two parameters for the operator function rather than one (in reality a member function of a class always has an invisible parameter called 'this' which is passed to the function, so they both have two parameters).
    Last edited by 7stud; 10-16-2005 at 12:44 AM.

  9. #9
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    Thanks Thantos.

    7stud, I understand a little better now. Thank you. Using Thantos's advice (but changing some things around to get rid of errors), I got my program working, but I am confused from the way it's acting.

    This function:
    Code:
    float operator*(int x, const percent& y)
    {
    	return y * x;
    }
    will let me use the statement c = a * f; in my main function.
    But if I switch the function defintion around to return x * y;, nothing appears in the console window. So I told myself not to be picky and as long as it works, I'm good to go. My only concern is the division. If I wanted to do c = a / f; that causes the division to go backwards if I return y * x;.

    Any ideas on why y has to be before x for a number to appear on the console and how to fix this problem?

    Thanks for your help.

  10. #10
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    But if I switch the function defintion around to return x * y;, nothing appears in the console window.
    Because you are defining a function in terms of it self (recursion) without any type of base case.
    y * x works because you have already defined a function that returns a result for when you multiply a percent by a number.
    You are now trying to define a function for when you multiply a number by a percent.

    put:
    Code:
    std::cout<<"I'm gonna try to use x * y"<<std::endl;
    right before the return and you'll see the recursion

  11. #11
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    So the function that returns y * x depends on the other operator* function (the one that multiplies the percent by a number)? If this is so, is it because that function has a base case?

    How would the definition of the operator/ function look like?

  12. #12
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    that you'd probably have to code seperatly. You should ask yourself if it makes sense to divide an int by a percent and if so what the operation would look like

  13. #13
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    Isn't that a flaw in my program that the function to multiply a number by a percent relies on the function to multiply a percent by a number?

    Also, I try to call getpercent() in my second operator/ function, and it won't let me, even though the function is a friend of the class. Is there something I'm missing?
    Last edited by webren; 10-16-2005 at 09:49 AM.

  14. #14
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Isn't that a flaw in my program that the function to multiply a number by a percent relies on the function to multiply a percent by a number?
    nope, in fact it shows a good level of abstraction

    Also, I try to call getpercent() in my second operator/ function, and it won't let me, even though the function is a friend of the class. Is there something I'm missing?
    Wow thats so specific. Ok won't let you, won't let you, oh I bet the compiler does like you. Post the error and the code!

  15. #15
    Registered User
    Join Date
    Apr 2005
    Posts
    36
    Code:
    float operator/(int x, const percent& y)
    {
    	float a, b;
            percent e;
    	
    	a = e.getpercent();
            b = a / y;
    
    	return b;
    }
    This is the error I receive: "error C2065: 'getpercent' : undeclared identifier"
    When I change a = getpercent(); to a = percent::getpercent(), the error message says: "error C2352: 'percent::getpercent' : illegal call of non-static member function"

    EDIT: Okay, I needed to access it using an object, which made it error free. Still comes up as a blank console window, though.
    Last edited by webren; 10-16-2005 at 02:14 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overloading operators
    By ugmusicbiz in forum C++ Programming
    Replies: 2
    Last Post: 02-13-2009, 01:41 PM
  2. unary operator overloading and classes
    By coletek in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2009, 02:14 AM
  3. overloading operator problems
    By almich in forum C++ Programming
    Replies: 2
    Last Post: 07-26-2004, 04:10 PM
  4. operator overloading
    By blue_gene in forum C++ Programming
    Replies: 6
    Last Post: 04-29-2004, 04:06 PM
  5. overloading
    By theLukerBoy in forum C++ Programming
    Replies: 6
    Last Post: 11-04-2002, 08:49 PM