c++ overloading assignment operator of another class
Asked Answered
C

3

6

i have a c++ class to handle fractions and i want it to allow conversion to double,
i have something like that :

class fraction  
{  
    double n,d;  
public:  
    fraction(double _n, double _d) {n = _n; d = _d;}  
    //some functions  
    double todouble() {return n/d;}  
};  

fraction frac(1,2);  
double dbl = frac.todouble();  

which works fine, but i want to overload the assignment operator so i can go directly with :

double dbl = frac;  

i tried to add this :

double double::operator =(double& dbl, fraction& frac) {return dbl = frac.n / frac.d;}  

which resulted in the following compilation error :

 error: ‘double fraction::operator=(double&, fraction&)’ must take exactly one argument  

what am i doing wrong?

Collaborative answered 4/4, 2014 at 9:59 Comment(4)
See this reference. The assignment operator can't be overloaded as a stand-alone (non-member) function.Burton
If you have control of the class, and can modify it, you can make a conversion operator: operator double() const { return todouble(); } It must still be a member function though.Burton
double is not a class and does not have members.Helmick
In general, I would advise to shy away from implicit conversions. Sure explicit conversions (such as todouble) are slightly more verbose, but on the other hand they only occur exactly where you want them.Ella
G
2

If you want the ability to assign a double to fraction you can declare a non-explicit constructor:

fraction(double d = 0, double n = 1) : d(d), n(n) {}

and for reverse

operator double() const { return n/d; }

and then

fraction f;

f = 12.5;      // Assign a double to fraction

double x = f;  // Assign fraction as double to a double
Gerrygerrymander answered 4/4, 2014 at 10:7 Comment(2)
Providing both ways as implicit conversion opportunities will mean that you can use both wherever any of the two types is required, and more, since this makes e.g. implicit conversion from fraction to int possible. This is a dangerous thing to do, as you will get lots of ambiguities and silent conversions that should be errors.Intercommunicate
The constructor signature should be fraction(double n = 0, double d = 1).Indifferentism
G
3

What you need is conversion operator:

operator double() const { return n / d; }
Geis answered 4/4, 2014 at 10:7 Comment(0)
I
3

You cannot overload an assignment operator as a free function, meaning it must be a class member. Since double is no class, that means you have no way to write an assignment afor double.

The only thing that is left is writing a conversion operator for your class:

class Fraction {
  //...
public:
  double toDouble() const { return n/d; } 
  operator double() const { return toDouble(); } 
};

Having said that, this means you can use a fraction wherever you need a double, int, float, because the compiler uses the operator for implicit conversions, not only to double but also to int and other types that have possible builtin conversion from double. This can be desired for some classes, but it can lead to ambiguities and errors, because one often overlooks the conversion opportuinities the compiler takes into account.

In C++11 there is the possibility to make the operator explicit:

  explicit operator double() const { return toDouble(); } 

This would mean that implicit conversion are not allowed, and copy-initialization won't work, but direct initialization will:

 double dbl = frac;  //Error
 double dbl{frac};   //Ok 

A little sidenote: you should make that conversion function const.

Intercommunicate answered 4/4, 2014 at 10:17 Comment(0)
G
2

If you want the ability to assign a double to fraction you can declare a non-explicit constructor:

fraction(double d = 0, double n = 1) : d(d), n(n) {}

and for reverse

operator double() const { return n/d; }

and then

fraction f;

f = 12.5;      // Assign a double to fraction

double x = f;  // Assign fraction as double to a double
Gerrygerrymander answered 4/4, 2014 at 10:7 Comment(2)
Providing both ways as implicit conversion opportunities will mean that you can use both wherever any of the two types is required, and more, since this makes e.g. implicit conversion from fraction to int possible. This is a dangerous thing to do, as you will get lots of ambiguities and silent conversions that should be errors.Intercommunicate
The constructor signature should be fraction(double n = 0, double d = 1).Indifferentism

© 2022 - 2024 — McMap. All rights reserved.