Main.cpp
#include <iostream>
#include "rationalsCN.h"
using namespace std;
using namespace Carson;
int main() {
Rational r1(3, 5);
Rational r2(7);
Rational r3;
cout << "Enter a rational number in the format numerator/denominator: ";
cin >> r3;
cout << "r1 = " << r1 << endl;
cout << "r2 = " << r2 << endl;
cout << "r3 = " << r3 << endl;
cout << "r1 == r2: " << (r1 == r2) << endl;
cout << "r1 != r2: " << (r1 != r2) << endl;
cout << "r1 < r2: " << (r1 < r2) << endl;
cout << "r1 <= r2: " << (r1 <= r2) << endl;
cout << "r1 > r2: " << (r1 > r2) << endl;
cout << "r1 >= r2: " << (r1 >= r2) << endl;
Rational sum = r1 + r2;
Rational diff = r1 - r2;
Rational prod = r1 * r2;
Rational quotient = r1 / r2;
cout << "r1 + r2 = " << sum << endl;
cout << "r1 - r2 = " << diff << endl;
cout << "r1 * r2 = " << prod << endl;
cout << "r1 / r2 = " << quotient << endl;
Rational zero;
Rational divByZero(3, 0);
Rational zeroByZero(0, 0);
Rational zeroInNum(0, 3);
Rational negNum(-3, 8);
Rational negDenom(3, -8);
Rational negBoth(-3, -8);
cout << "zero = " << zero << endl;
cout << "divByZero = " << divByZero << endl;
cout << "zeroByZero = " << zeroByZero << endl;
cout << "zeroInNum = " << zeroInNum << endl;
cout << "negNum = " << negNum << endl;
cout << "negDenom = " << negDenom << endl;
cout << "negBoth = " << negBoth << endl;
return 0;
}
字符串
- 中国.h**
#include <iostream>
namespace Carson {
class Rational {
int num, denom;
int gcd(int a, int b);
void reduce();
void initialize(int n, int d);
public:
Rational();
Rational(int n);
Rational(int n, int d);
friend std::istream& operator>>(std::istream& is, Rational& r);
friend std::ostream& operator<<(std::ostream& os, const Rational& r);
friend bool operator==(const Rational& r1, const Rational& r2);
friend bool operator<(const Rational& r1, const Rational& r2);
friend bool operator<=(const Rational& r1, const Rational& r2);
friend bool operator>(const Rational& r1, const Rational& r2);
friend bool operator>=(const Rational& r1, const Rational& r2);
friend bool operator!=(const Rational& r1, const Rational& r2);
friend Rational operator+(const Rational& r1, const Rational& r2);
friend Rational operator-(const Rational& r1, const Rational& r2);
friend Rational operator*(const Rational& r1, const Rational& r2);
friend Rational operator/(const Rational& r1, const Rational& r2);
friend Rational operator-(const Rational& r);
};
}
#endif
型
[*]中国.cpp**
#include "rationalsCN.h"
namespace Carson {
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
namespace Carson {
Rational::Rational(int numerator, int denominator) {
if (denominator == 0) {
throw std::invalid_argument("Denominator can't be zero");
}
int divisor = gcd(numerator, denominator);
num = numerator / divisor;
denom = denominator / divisor;
if (denom < 0) {
num *= -1;
denom *= -1;
}
}
Rational::Rational(int numerator) : Rational(numerator, 1) {}
Rational::Rational() : Rational(0, 1) {}
std::ostream& operator<<(std::ostream& os, const Rational& r) {
os << r.num << "/" << r.denom;
return os;
}
std::istream& operator>>(std::istream& is, Rational& r) {
int numerator, denominator;
char slash;
is >> numerator >> slash >> denominator;
if (!is || slash != '/') {
is.setstate(std::ios_base::failbit);
return is;
}
r = Rational(numerator, denominator);
return is;
}
bool operator==(const Rational& r1, const Rational& r2) {
return r1.num == r2.num && r1.denom == r2.denom;
}
bool operator<(const Rational& r1, const Rational& r2) {
return r1.num * r2.denom < r2.num * r1.denom;
}
bool operator<=(const Rational& r1, const Rational& r2) {
return r1.num * r2.denom <= r2.num * r1.denom;
}
bool operator>(const Rational& r1, const Rational& r2) {
return r1.num * r2.denom > r2.num * r1.denom;
}
bool operator>=(const Rational& r1, const Rational& r2) {
return r1.num * r2.denom >= r2.num * r1.denom;
}
bool operator!=(const Rational& r1, const Rational& r2) {
return !(r1 == r2);
}
Rational operator+(const Rational& r1, const Rational& r2) {
int lcm = (r1.denom * r2.denom) / gcd(r1.denom, r2.denom);
int num = (lcm / r1.denom) * r1.num + (lcm / r2.denom) * r2.num;
return Rational(num, lcm);
}
Rational operator-(const Rational& r1, const Rational& r2) {
return r1 + Rational(-r2.num, r2.denom);
}
Rational operator*(const Rational& r1, const Rational& r2) {
return Rational(r1.num * r2.num, r1.denom * r2.denom);
}
Rational operator/(const Rational& r1, const Rational& r2) {
if (r2.num == 0) {
throw std::invalid_argument("division by zero");
}
return Rational(r1.num * r2.denom, r1.denom * r2.num);
}
Rational operator-(const Rational& r) {
return Rational(-r.num, r.denom);
}
}
型
我得到这些错误
/usr/bin/ld: /tmp/cczoz2hS.o: in function Carson::Rational::Rational(int, int)':
rationalsCN.cpp:(.text+0x9c): undefined reference to Carson::Rational::gcd(int, int)'
collect2: error: ld returned 1 exit status
型
我以前从来没有遇到过这个错误,而且它没有说明它在哪一行。我知道它在rationalsCN.cpp中,但我不确定要修改什么。而且我相信可能有更有效的方法来完成我所做的事情。
2条答案
按热度按时间khbbv19g1#
四个变化
我做了四处改动来编译你的程序。
1.将include guard添加到文件
RationsCN.h
中。您的代码可能已经有了这个,但它没有在SO中发布。1.使
gcd
成为类Rational
的静态函数。目前,它是一个成员函数。您可能希望删除此函数,以支持std::gcd
。1.将函数
gcd
的定义范围限定为RationsCN.cpp
文件中的Rational
类。1.将对函数
gcd
的引用的作用域设置为函数operator+
中的类Rational
。现在它可以运行了,但是当您在构造函数
Rational(int numerator, int denominator)
中调用gcd
时,会抛出异常。使用静态函数
字符串
作用域函数
gcd
的定义型
友元函数中对函数
gcd
的作用域引用型
建议
写作课
Rational
对C++学生来说是一个很好的练习。很高兴看到你接受挑战。下面是一些提示。
1.使用类型
long long int
,而不是int
。这会给你更多的空间,在一系列的计算导致分母爆炸之前。我在一个矩阵求逆程序中使用Rational
作为元素类型时看到了这一点!1.请参见Comparing Rational Numbers Without Overflow。
1.请参阅Boost implementation of
operator+=
,了解一些延迟溢出的优化技巧。1.根据其Map的复合指派运算子,实作二元运算子,例如
+
、-
、*
和/
。例如:型
玩得开心点!
oyt4ldly2#
在MySQL. h中,
gcd
是命名空间Carson
中类Rational
的方法。gcd
是命名空间Carson
中的一个函数。就像Richard和JaMiT评论的那样,头文件可以编译,但没有
Rational::gcd
的实现。最小的改动是从MySQL. h中删除
gcd
的声明。只有cpp文件能够访问它。您也可以将其设置为静态的。如果你需要
gcd
可以被其他类访问,你可以:gcd
成为静态的。更新BSCN.cpp以实现Rational::gcd
而不仅仅是gcd
。gcd
成为Rational
类之外但在Carson
命名空间内的函数。