一個簡單的C++實現有理數類的例子
阿新 • • 發佈:2018-11-13
這次本來是老師佈置的一個作業,老師提前把main.cpp給了我們,要求我們在標頭檔案中定義並且實現一個有理數類,使得執行程式後輸出的結果跟他給的一樣。
main.cpp如下:
#include <stdio.h> #include "Rational.h" int main() { Rational num1(1, 3), num2(3, 1), num3(2, 6); Rational result; result = num1 + num2; printf("%s + %s = %s\n", num1.value(), num2.value(), result.value()); result = num1 * num2; printf("%s * %s = %s\n", num1.value(), num2.value(), result.value()); printf("%s is%s equal to %s\n", num1.value(), (num1 == num2) ? " " : " not", num2.value()); printf("%s is%s equal to %s\n", num1.value(), (num1 == num3) ? " " : " not", num3.value()); system("pause"); return 0; }
分析可知需要定義兩個建構函式,一個預設的建構函式,一個是帶兩個int型別引數的建構函式,並且還要過載三個操作符,分別是" + "," * "," == "。在實現的過程中最麻煩應該是value這個方法了,下面等會兒再說。
我們先來看main.cpp的程式碼。
Rational num1(1, 3), num2(3, 1), num3(2, 6);
Rational result;
第一行屬於隱式的呼叫建構函式,第二行呼叫了預設建構函式(呼叫預設建構函式就只有這一種寫法),還有一種顯示的呼叫建構函式的方法,對於上面的程式碼可改寫為:
Rational num1 = Rational(1,3), num2 = Rational(3,1), num3 = Rational(2,6);
Rational result;
繼續往下看。對於printf函式,這兒涉及到一個知識點,如下圖所示
所以我們在編寫標頭檔案中的value函式時需要明白該函式的返回值型別為char型別,注意!!!既不是string型別,也不是char型別。
在實現這個有理數類的時候,我們需要認識到兩個點,其一需要實現化簡操作,其二需要注意分母為負數時應該把負號傳給分子(至於分母不能為0這個情況,在程式碼中操作對分母進行操作時加以限制即可)。我將這兩個需要注意的問題都寫到了narmalize()函式中,對於化簡操作,先使用歐幾里得演算法求出最大公約數,然後分子分母同時除以它即可。
操作符過載后里面的實現方法沒什麼可說的,都是數學問題。
至於value函式,想讓它返回值為char型別比較麻煩。首先,一個分式由分子," / " ,分母這三部分組成,其中分子分母是整型," / "是一個運算子,最先想到的方法是使用C++的to_string()方法把分子跟分母轉成字串,然後直接使用" + "號將三個字串連線起來,這樣就可以使得整個分式變成一個字串了。下面應該考慮將string型別轉成char型別,在網上搜索後發現有兩種方法:
data()和c_str(),然而把程式碼寫好以後還沒執行vs就報錯,說返回值型別與函式型別不一致,仔細一看,原來使用上面兩種方法的返回值都是const char
對了,在執行時報了一個說strcpy是一個不安全的函式這個的錯誤,經過查詢明白了,新版本的vs認為strcpy、scanf等函式不安全,建議使用strcpy_s()這個新函式,其用法跟原來的函式相差不大。還有一種解決該報錯的方法,滑鼠先選中"解決方案資源管理器"中的專案名,然後按照下面的步驟設定:
專案 ->屬性 -> c/c++ -> 前處理器 -> 點選前處理器定義,編輯,加入_CRT_SECURE_NO_WARNINGS,即可。
下面是標頭檔案的程式碼
#include<math.h>
#include<iostream>
#include<string>
class Rational
{
public:
Rational();//預設建構函式
Rational(int num, int denom);//自定義建構函式
~Rational();//解構函式
Rational operator+(Rational rhs);//操作符過載
Rational operator-(Rational rhs);
Rational operator*(Rational rhs);
int operator==(Rational rhs);
char* value();
private:
int numerator;//分子
int denominator;//分母
void normalize();//化簡
};
Rational::Rational()
{
}
Rational::Rational(int num, int denom)
{
numerator = num;
denominator = denom;
normalize();
}
Rational::~Rational()
{
}
void Rational::normalize()
{
if (denominator < 0)
{
numerator = -numerator;
denominator = -denominator;
}
//求出分子和分母的最大公約數,用歐幾里得演算法
int a = abs(numerator);
int b = abs(denominator);
while (b>0)
{
int t = a%b;
a = b;
b = t;
}
numerator /= a;
denominator /= a;
}
Rational Rational::operator+(Rational rhs)
{
int a = numerator;
int b = denominator;
int c = rhs.numerator;
int d = rhs.denominator;
int e = a*d+ b*c;
int f = b*d;
return Rational(e, f);
}
Rational Rational::operator-(Rational rhs)
{
rhs.numerator = -rhs.numerator;
return operator+(rhs);
}
Rational Rational::operator*(Rational rhs)
{
int a = numerator;
int b = denominator;
int c = rhs.numerator;
int d = rhs.denominator;
int e = a*c;
int f = b*d;
return Rational(e, f);
}
int Rational::operator==(Rational rhs)
{
int a = numerator;
int b = denominator;
int c = rhs.numerator;
int d = rhs.denominator;
if (a / b == c / d) {
return 1;
}
else
{
return 0;
}
}
char* Rational::value()
{
std::string x;
x = std::to_string(numerator)+ "/" + std::to_string(denominator);//轉成string型別
const char* p= x.c_str();//轉成const char*型別
char *m = new char[100];//轉成char*型別
strcpy_s(m, 101, p);//新版本的vs要求使用strcpy_s()函式
return m;
}