转换构造函数不会将“2”转换为“2”进入运算符 + 中的用户定义类型
我有一个名为 Fraction 的类:
#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;
}
并且我正在尝试执行操作 Fraction 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;
}
I have a class called Fraction :
#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
with the next implementation file :
#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;
}
and I'm trying to do the action Fraction f4=f2+2; but I get the following compiler error:
..\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&)
But how could that be , if I have a conversion Constructor (please notice the Ctor in the .h file with the default values) with one argument which is suppose to convert the "2" into a Fraction ...then what's might the be the problem ?
thanks
Ronen
Edit :
here's the main file (if it would help)
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器无法决定是将
f2
转换为double
然后添加double
和int
,还是构造 Fraction从2
然后添加两个分数。选项:
The compiler can't decide whether to convert
f2
todouble
then adddouble
andint
, or to construct Fraction from2
then add two fractions.Options:
问题是:
在您的
Fraction
类中定义。在评估时,
编译器有 2 个选择:
第一个选择:
编译器可以使用您提供的运算符函数将
f2
转换为double
,然后可以用于调用内置运算符函数:第二种选择:
编译器可以使用构造函数将
2
转换为Fraction
对象,然后调用:两者选择会导致歧义,然后编译器会抱怨并报告给你。
解决方案:
更改 double 运算符函数的名称。
Problem is:
defined inside your
Fraction
class.While evaluating,
Compiler has 2 choices:
First Choice:
The compiler can convert
f2
to adouble
using your provided operator function and then it can be used to call the inbuilt operator function:Second Choice:
The compiler can convert
2
to a object ofFraction
using constructor and then call:The two choices cause an ambiguity and then the compiler complains and reports it to you.
Solution:
Change the name of the
double
operator function.当您编写类似
f2+2
的内容时,编译器确实可以做出两种选择。您必须使构造函数显式化,或者为双精度运算符指定一个显式名称(例如 toDouble)来解决问题。
The compiler can indeed make 2 choices when you write something like
f2+2
.You will have to make either the constructor explicit, or give the double-operator an explicit name (e.g. toDouble) to solve the problem.