Theo như mình thấy, bạn làm thế cũng đúng yêu cầu đề bài, tuy nhiên tư duy thì hơi ngắn, hoặc là do em mới chỉ biết 1 hình thức khai báo của phương thức/hàm.
- Đã là class, em nên xây dựng cho nó phương thức khởi tạo thay vì hàm tạo mặc định.
- Phương thức
rutGon
là phương thức của đối tượng. Giả sử em có 2 đối tượng phân số ps1
và ps2
, em gọi phương thức ps1.rutGon(ps2)
thì nó sẽ rút gọn ps2
, em thấy có buồn cười không 
Cách giải quyết là viết phương thức tác động trực tiếp lên đối tượng this
(anh viết rút gọn, không có this
nhé), đồng thời thay đổi thuật toán để rút gọn cả phân số âm:
void PhanSo::rutGon()
{
if (_ms < 0)
{
_ms = -_ms;
_ts = -_ts;
}
for (int i = 2; i <= abs(abs(_ts) - abs(_ms)); i += 1)
while (_ts % i == 0 && _ms % i == 0)
{
_ts /= i;
_ms /= i;
}
}
Như vậy, khi muốn rút gọn phân số ps69
, ta chỉ việc ps69.rutGon();
thậm chí nếu gọi phương thức bằng các phương thức của chính đối tượng đó thì chỉ cần rutGon();
- Phương thức
nhap
của em nó rất ư là có vấn đề vì không kiểm tra điều kiện. Cái này là tối kỵ nhé.
- Phương thức
xuat
của em nên viết riêng cho trường hợp giá trị của phân số là số nguyên.
- Phương thức
cong
của em chưa rút gọn phân số.
- Phương thức
cong
, em phải tư duy khác một chút: Bởi vì phép cộng của 2 phân số sẽ cho kết quả là 1 phân số, thế nên em nên trả về kiểu dữ liệu PhanSo
thay vì kiểu dữ liệu void
Nếu là anh, anh sẽ viết chương trình phức tạp hơn 1 chút như sau (Vì anh viết phương thức cong
trả về kiểu dữ liệu PhanSo
nên anh viết hàm đó nằm ở ngoài class. Vì hàm nằm ở ngoài class thì không truy cập được vào các thuộc tính private
nên anh viết thêm phương thức Get
):
#include <iostream>
#include <string>
using namespace std;
class PhanSo
{
private:
int TuSo = 0;
int MauSo = 1;
public:
PhanSo()//Nạp chồng phương thức khởi tạo mặc định
{
TuSo = 0;
MauSo = 1;
}
PhanSo(int ts, int ms)//Xây dựng phương thức khởi tạo có tham số
{
if (ms == 0)
{
cout << "Loi: Mau so bang 0. Khoi tao phan so mac dinh" << endl;
TuSo = 0;
MauSo = 1;
}
else
{
TuSo = ts;
MauSo = ms;
RutGon();
}
}
void RutGon()
{
if (TuSo == 0)
MauSo = 1;
if (MauSo < 0)
{
MauSo = -MauSo;
TuSo = -TuSo;
}
for (int i = 2; i <= abs(abs(TuSo) - abs(MauSo)); i += 1)
while (TuSo % i == 0 && MauSo % i == 0)
{
TuSo /= i;
MauSo /= i;
}
}
string ToString()
{
if (MauSo == 1)
return to_string(TuSo);
return to_string(TuSo) + "/" + to_string(MauSo);
}
void Nhap()
{
cout << "Nhap tu so: ";
cin >> TuSo;
cout << "Nhap mau so: ";
cin >> MauSo;
if (MauSo == 0)
{
cout << "Loi: Mau so bang 0. Khoi tao phan so mac dinh" << endl;
TuSo = 0;
MauSo = 1;
}
else
RutGon();
}
void Xuat()
{
cout << "Gia tri phan so: " << ToString() << endl;
}
int GetTuSo()
{
return TuSo;
}
int GetMauSo()
{
return MauSo;
}
};
PhanSo Cong(PhanSo PS1, PhanSo PS2)
{
int ts1 = PS1.GetTuSo();
int ts2 = PS2.GetTuSo();
int ms1 = PS1.GetMauSo();
int ms2 = PS2.GetMauSo();
return PhanSo(ts1*ms2 + ts2*ms1, ms1*ms2);
}
void main()
{
PhanSo ps1, ps2;
ps1.Nhap();
ps1.Xuat();
ps2.Nhap();
ps2.Xuat();
ps1.RutGon();//Thực ra không cần thiết vì đã rút gọn ở phương thức khởi tạo
ps2.RutGon();//Thực ra không cần thiết vì đã rút gọn ở phương thức khởi tạo
cout << "Tong 2 phan so: " << Cong(ps1, ps2).ToString() << endl;
system("pause");
}