argument type checkinng in Constructor
-
Yes I did get a warning. But it is not enough. I want it to be error in the compile process. Do you know how?
-
add a declaration of an overload:
Ration(double n, double d);
but don't implement it.
When the Compiler selects this constructor as the most fitting one you'll get a linker error because it's not implemented. For a compile-time error you might consider making it private.
-
Thanks for your answer. Still not working. It looks like a simple problem but I try so many approaches already.
-
Try this:
explicit Rational( int n, int d);This will forbid implicit typecasts resulting in a compile time error when you try to pass other types than int.
-
no it doesn't.
It prevents automatic conversion which isn't possible anyway with two arguments.
notkit:
what doesn't work?
Could you show an example?
-
Look interesting. I try it as you suggested but the constructor Rational(int n, int d) is still called when I call Rational(3.0, 4.0). The "3.0" and "4.0" are converted into integer and only warning are given.
-
try this:
class Rational { public: Rational(int n, int d) { // your Code here } private: Rational(double n, double d); // no implmentation }; int main() { Rational(2,3); // should work fine Rational(2.0,3.0); // should result in a compilation error }
-
Here you are. Class Rational is to represent rational number (e.g. 3/4) and normally a double should not be able to expressed as rational number.
// this is the header file
class Rational
{
public:
// Constructor
Rational(int n = 0, int d = 1) // denomiator alway more than zero
{
if (d != 0) {
m_num = n;
m_den = d;
if(m_den != 1)
Normalize();
}
}// operators
Rational &operator =(int i);operator double() { return (double)m_num/(double)m_den; }
Rational operator +() { return Rational(m_num, m_den); }
Rational operator -() { return Rational(-m_num, m_den); }Rational operator +(const Rational &src);
double operator +(const double d);
Rational operator -(const Rational &src);
double operator -(const double d);
Rational operator *(const Rational &src);
double operator *(const double d);
Rational operator /(const Rational &src);
double operator /(const double d);// Print out the contents of the instance
void Print(); // Implemented in the rational.cpp file// Access member functions
int Numerator() { return m_num; }
int Denominator() { return m_den; }private:
// Private functions
void Normalize(); // To be implemented in the rational.cpp file// Private data
int m_num; // numerator
int m_den; // denominator
};//
int main()
{
a = 1.0; // Should not compile
a = Rational(3.0, 3.0); // Should not compilereturn 0;
}
-
This is the implementation for Rational class.
#include <iostream.h>
#include "rational.h"void Rational::Normalize()
{
if (m_den<0) {
m_num = -m_num;
m_den = -m_den;
} else {
m_num = m_num;
m_den = m_den;
}if (m_num == 0) {
return;
}// Euclid's algorithm...
int a, b, r;if (m_num > 0 && m_num > m_den) {
a = m_num;
b = m_den;
} else if (m_num > 0){
a = m_den;
b = m_num;
} else if (-m_num > m_den) {
a = -m_num;
b = m_den;
} else {
a = m_den;
b = -m_num;
}r = 1;
while (r > 0)
{
r = a % b;
a = b;
b = r;
}// record the normalized value to m_num and m_den
m_num = m_num/a;
m_den = m_den/a;return;
}
void Rational::Print()
{
cout << "(" << m_num << "/" << m_den << ")";
}Rational &Rational::operator =(int i)
{
m_num = i;
m_den = 0;
return *this;
}Rational Rational::operator +(const Rational &src)
{
return( Rational( m_num*src.m_den + src.m_num*m_den, m_den*src.m_den ) );
}double Rational::operator +(const double d)
{
return( double(m_num)/double(m_den) + d );
}Rational Rational::operator -(const Rational &src)
{
return( Rational( m_num*src.m_den - src.m_num*m_den, m_den*src.m_den ) );
}double Rational::operator -(const double d)
{
return( double(m_num)/double(m_den) - d );
}Rational Rational::operator *(const Rational &src)
{
return( Rational( m_num*src.m_num, m_den*src.m_den ) );
}double Rational::operator *(const double d)
{
return( double(m_num)/double(m_den) * d );
}Rational Rational::operator /(const Rational &src)
{
return( Rational( m_num*src.m_den, m_den*src.m_num ) );
}double Rational::operator /(const double d)
{
return( double(m_num)/double(m_den) / d );
}
-
Beats me where you left Jester's suggestion. Already disposed of it?
You should honestly give it a try; public for linker-, private for compiler-error.NB:
Rational &Rational::operator =(int i) { m_num = i; // m_den = 0; // this ain't exactly what you want, is it? how 'bout that: m_den = 1; return *this; } // moreover, if (m_den<0) { m_num = -m_num; m_den = -m_den; } // else branches aren't mandatory ;) /* else { m_num = m_num; m_den = m_den; } */
-
to Jester,
cool. The Rational(3.0, 4.0) does not compile now. But the
Rational a;
a = 3.0; // Ratinal = double should not compilestill compiles. And this should not because double should not be expressed as Rational numbers.
-
use the same technique for operator=
-
Oh finally. Problem solved. I was like trying to solve this easy-looking problems for days. Danke Sehr! Danke schon! Danke Danke! Ho!