2011-08-31 3 views
2

I 클래스라는 분수가 : 다음 구현 파일에변환 생성자 +

#ifndef FRACTION_H 
#define FRACTION_H 

#include <iostream> 
using namespace std; 

class Fraction 
{ 
    // data 
    int m_iNom; 
    int m_iDenom; 

    // operations 
    int gcd (int i, int j); 
    void reduce(); 

public: 

Fraction (int nn=0, int dn=1); // 1 declaration = 3 constructors 
Fraction (const Fraction& fr); //C.Ctor 
~Fraction(); //Dtor 
Fraction& operator = (const Fraction &fr); //assignment 

Fraction& operator ++(); // prefix - ++a 
    const Fraction operator ++ (int); // postfix - a++ 

    friend const Fraction operator + (const Fraction &f1, const Fraction &f2); 
    friend const Fraction operator - (const Fraction &f1, const Fraction &f2); 
    friend const Fraction operator * (const Fraction &f1, const Fraction &f2); 
    friend const Fraction operator/(const Fraction &f1, const Fraction &f2); 

Fraction& operator += (const Fraction &f); 

    operator double() { return double (m_iNom)/m_iDenom; } //casting operator 

    friend istream& operator >> (istream &is, Fraction &f); 
    friend ostream& operator << (ostream &os, const Fraction &f); 
    const int& operator[] (int i) const; 
    int& operator [] (int i); 


}; 
#endif 

:

#include "Fraction.h" 
#include <iostream> 
using namespace std; 


Fraction::Fraction (int nn, int dd) : 
    m_iNom (nn), m_iDenom (dd) { 
    if (m_iDenom == 0) 
    m_iDenom = 1; 
reduce(); 
cout<<"Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl; 
} 


Fraction::Fraction (const Fraction & fr){ 
m_iNom=fr.m_iNom; 
m_iDenom=fr.m_iDenom; 
cout<<"C.Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl; 
} 

Fraction::~Fraction() { 
cout<<"del: "<<m_iNom<<"/"<<m_iDenom<<endl; 
} 


int Fraction::gcd (int i, int j) { 
    if ((i == 0) || (j == 0)) 
    return i + j; 
    while (i %= j) { 
    int t = i; 
    i = j; 
    j = t; 
} 
    return j; 
} 


void Fraction::reduce() { 
    int g = gcd (m_iNom, m_iDenom); 
m_iNom /= g; 
m_iDenom /= g; 
} 


const Fraction operator + (const Fraction &f1, const Fraction &f2) { 
    int nn = f1.m_iNom * f2.m_iDenom + f1.m_iDenom * f2.m_iNom; 
    int dd = f1.m_iDenom * f2.m_iDenom; 
    return Fraction (nn, dd); 
} 


const Fraction operator - (const Fraction &f1, const Fraction &f2) { 
    int nn = f1.m_iNom * f2.m_iDenom - f1.m_iDenom * f2.m_iNom; 
    int dd = f1.m_iDenom * f2.m_iDenom; 
    return Fraction (nn, dd); 
} 


const Fraction operator * (const Fraction &f1, const Fraction &f2) { 
    int nn = f1.m_iNom * f2.m_iNom; 
    int dd = f1.m_iDenom * f2.m_iDenom; 
    return Fraction (nn, dd); 
} 


const Fraction operator/(const Fraction &f1, const Fraction &f2) { 
    int nn = f1.m_iNom * f2.m_iDenom; 
    int dd = f1.m_iDenom * f2.m_iNom; 
    return Fraction (nn, dd); 
} 


Fraction& Fraction::operator = (const Fraction &f) 
{ 
m_iNom = f.m_iNom; 
m_iDenom = f.m_iDenom; 
cout<<"OP = - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl; 
    return *this; 
} 


Fraction& Fraction::operator += (const Fraction &f) { 
(*this) = (*this) + f; 
    return *this; 
} 


Fraction& Fraction::operator ++() 
{ 
m_iNom += m_iDenom; 
reduce(); 
    return *this; 
} 


const Fraction Fraction::operator ++ (int) 
{ 
    int nn = m_iNom; 
    int dd = m_iDenom; 
m_iNom += m_iDenom; 
reduce(); 
    return Fraction (nn, dd); 
} 


istream& operator >> (istream &is, Fraction &frac) 
{ 
    char divSign; 
is >> frac.m_iNom >> divSign >> frac.m_iDenom; 
    if (frac.m_iDenom == 0) 
    frac.m_iDenom = 1; 
frac.reduce(); 
    return is; 
} 


ostream& operator << (ostream& os, const Fraction &frac) 
{ 
    return os << frac.m_iNom << "/" << frac.m_iDenom; 
} 


int& Fraction::operator [] (int i){ 
cout<<"reg []"<<endl; 
    if (i==1) 
    return m_iNom; 
    return m_iDenom; 
} 


const int& Fraction::operator[] (int i) const{ 
cout<<"const []"<<endl; 
    if (i==1) 
    return m_iNom; 
    return m_iDenom; 
} 

와 I를 행동을하려고하는 것 분수 f4 = f2 + 2; 나는 변환 생성자가있는 경우

..\main.cpp:13: error: ambiguous overload for 'operator+' in 'f2 + 2' 
..\main.cpp:13: note: candidates are: operator+(double, int) <built-in> 
..\Fraction.h:27: note:     const Fraction operator+(const Fraction&, const Fraction&) 

그러나이 될 수 있는지, (기본 값으로 .H 파일에서의 ctor주의하시기 바랍니다)에 가정 하나 개 인수 :는하지만 다음과 같은 컴파일러 오류 "2"를 분수로 변환하면 ... 문제는 무엇일까요?

감사 Ronen에

편집 : (이 도움이 될 경우)

여기에 주요 파일의

#include <iostream> 
using namespace std; 

#include "Fraction.h" 

int main() { 
    Fraction f1(1,2); 
    Fraction f2(2); 
    Fraction f3; 

    Fraction f4=f2+2; // problem's here 
    f2+f2; 
    Fraction f5=f2-f1+f4; 
    return 0; 
} 
+2

질문 12 개가 물었습니다. 단 하나의 애너가 받아 들여지지 않았습니다 !! – Nawaz

+0

나는 당신의 의미를 이해하지 못합니다 ... –

+0

모두에게 감사합니다 !! –

답변

2

문제를 가지고하는 것은 :

operator double() 

정의 Fraction 클래스 안에 있습니다.

첫 번째 선택 :

평가하지만,

Fraction f4=f2+2; 

컴파일러는이 선택을 가지고

하여 제공하는 연산자 함수를 사용하여 double-f2을 변환 할 수 있습니다 다음이 될 수 있습니다 컴파일러 inbuilt 연산자 함수를 호출하는 데 사용됩니다.

operator+(double, int); 

두 번째 선택 :

다음 생성자를 사용 Fraction의 객체에 2를 변환 할 수 있습니다 컴파일러는 전화 :

const Fraction operator+(const Fraction&, const Fraction&) 

두 가지 선택

은 모호성을 야기하고 컴파일러가 불평하고 보고서를 너에게.

솔루션 :
변경 double 연산자 함수의 이름입니다.

+0

다른 해결책은 다음과 같습니다. 1. C++ 0x 컴파일러를 사용하는 경우 double() 연산자를 명시 적으로 만듭니다. 2. 연산자 + (const Fraction &, double)를 추가하십시오. 다른 것들도있을 수 있습니다 ... –

+0

@Michael : 해결 방법 3 : 변환 연산자를 '명시 적으로'사용하지 마십시오 (즉, C++ 0x를 사용하지 않는 것을 의미). –

3

컴파일러는 double-f2 다음 double를 추가 변환할지 여부를 결정할 수 없으며, int, 또는 2에서 분획을 구성하고, 두 분획을 첨가한다.

옵션 :

  • 만들기 연산자를 두 번() 명시 적으로 (C++ 11)
  • 과부하 연산자 +의 int에게
1

컴파일러는 실제로 f2+2과 같은 것을 쓸 때 2 가지 선택을 할 수 있습니다.

  • 먼저 분수의 생성자를 사용하여 2를 분수로 변환 한 다음 분수 + 연산자를 사용할 수 있습니다.
  • 그것은 먼저 분수의 이중 연산자를 사용하여 이중으로 F2를 변환 한 다음 단순히 더블 정수를 추가 할 수 있습니다
당신은 생성자 중 하나가 명시 적으로 만들거나 이중 운영자에게 명시 적으로 제공해야합니다

이름 (예 : toDouble)을 사용하여 문제를 해결하십시오.