trong C++ x + y được dịch theo 2 kiểu:
- Member function (hàm của class X):
x.operator+(y)
- Free function (hàm ko thuộc class nào):
operator+(x, y)
ở đây ko có kiểu 2, nên nó dịch theo kiểu 1, mà trong C++ khi gọi operator. trong x. thì x ko được chuyển kiểu tự động. Lý do là vì nếu x chuyển kiểu tự động được thì trình dịch phải kiểm tra tất cả các kiểu trong C++, ví dụ int -> float, int -> long int, int -> double, v.v… rồi chưa kể tới y nữa, nếu x có thể chuyển ngầm thành 100 kiểu, mỗi kiểu x lại có 100 kiểu cho y thì chuyển ngầm thử 10000 lần… làm vậy thì biên dịch 1 chương trình đơn giản chắc tới tết Congo nên nó ko làm. y có thể chuyển ngầm được vì class của x đã được xác định, số lượng hàm cần kiểm thử chuyển kiểu tự động cho y là nhỏ, ví dụ chỉ khoảng 100 kiểu hoặc 1 2 kiểu.
bạn muốn dòng cuối compile được thì định nghĩa 1 cái free function, xài friend hoặc tạo thêm 2 hàm lấy tử số, mẫu số cho PhanSo là được:
class PhanSo
{
friend PhanSo operator+(const PhanSo& lhs, const PhanSo& rhs); //lhs = left hand side = vế trái, rhs là vế phải
};
PhanSo operator+(const PhanSo& lhs, const PhanSo& rhs)
{
return PhanSo(lhs.ts*rhs.ms + rhs.ts*lhs.ms, lhs.ms*rhs.ms);
}
//hoặc ko cần friend:
class PhanSo
{
public:
int tuso()const { return ts; }
int mauso()const { return ms; }
};
PhanSo operator+(const PhanSo& lhs, const PhanSo& rhs)
{
return PhanSo(lhs.tuso()*rhs.mauso() + rhs.tuso()*lhs.mauso(), lhs.mauso()*rhs.mauso());
}
sở dĩ ở đây x được chuyển ngầm vì số lượng free function cho operator+ chỉ có tăng 1 chiều chứ ko tăng 2 chiều x y như x.operator+(y) kia nên chuyển ngầm thoải mái