01/10/2018, 10:09

Chuyển kiểu tự động của trình biên dịch trong C++

Mình có đoạn header như sau:

class PhanSo{
private:
int ts, ms;
public:
PhanSo (int ts=0, int ms=1);
PhanSo operator +(PhanSo);
};

Và các dòng lệnh sau:

PhanSo a, b(3, 4), c(2, 5);
a = b + c;
a = b + 3;
a = 3 + c;

Cho mình hỏi tại sao ở dòng thứ 3 thì số ‘3’ được chuyển kiểu tự động từ int sang PhanSo, còn ở dòng cuối cùng thì không ?

viết 12:20 ngày 01/10/2018
stackoverflow.com
Konrad Rudolph

No implicit conversion in overloaded operator

c++, operator-overloading, implicit-conversion
answered by Konrad Rudolph on 01:33PM - 12 Nov 10

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

Vincent Viết viết 12:26 ngày 01/10/2018

Cảm ơn bạn rất nhiều.

Bài liên quan
0