30/09/2018, 16:54

Không hiểu bản chất của tham chiếu?

cho mình hỏi khi mình overload toán tử thì 2 câu lệnh sau đều làm thay đổi giá trị của đối tượng gọi nó:
PhanSo operator + (const PhanSo&); //1
PhanSo& operator += (const PhanSo&); //2

vậy dòng 1 không có dâu tham chiếu tại sao nó vẫn thay đổi được giá trị đối tượng, vd: a=a+b thì a sẽ thay đổi luôn.
nếu như vậy thì dấu tham chiếu ở dòng 2 có ý nghĩa gì?
vì mình thấy bản chất code của 2 dòng là giống nhau mà.
nhờ cộng đồng diễn đàn giải đáp thắc mắc giúp mình.
cảm ơn,
Thông

... viết 19:10 ngày 30/09/2018

Bạn truyền tham chiếu của biến vào toán tử + qua tham số const PhanSo&
Trong hàm thực hiện thay đổi giá trị của PhanSo đó, và cái bạn trả về là giá trị của PhanSo sau khi đã thay đổi. Phân số kết quả được gán sau khi thực hiện phép cộng 2 phân số sẽ là gán giá trị, ko phải gán tham chiếu.

Bùi Trung Thông viết 19:09 ngày 30/09/2018

Bạn truyền tham chiếu của biến vào toán tử + qua tham số const PhanSo&

mình không hiểu lắm chỗ này, vd: a=a+b thì const PhanSo& chính là truyền tham chiếu của b vào chứ, còn a là đối tượng mình gọi mà.
mình vẫn chưa hiểu lắm câu trả lời của bạn.

... viết 19:07 ngày 30/09/2018

Thế thì bạn coi lại việc truyền tham số cho phép cộng, phép cộng cần 2 toán hạng chứ không phải 1.

Bùi Trung Thông viết 19:02 ngày 30/09/2018

a=a.operator+(b);
vẫn 2 chứ nhỉ toán hạng 1 là cái đối tượng a mình gọi, b là thứ 2, nếu khi dùng friend mới truyền vào luôn 2 chứ .

... viết 19:07 ngày 30/09/2018

operator là toán tử, không phải hàm, không dùng kiểu a.operator() được.

Tran Huan viết 19:03 ngày 30/09/2018

Mình sẽ giải thích về

PhanSo operator + (const PhanSo&); 

Thực ra toán tử này không hề làm thay đổi đối tượng a lẫn b trong phép toán a = a + b;

Lý do làm a thay đổi là phép gán = thông operator=

a + b ở đây sẽ tạo ra một phần tử mới và phần tử này được gán ngược lại cho a thông qua phép gán a = a + b;

Các bạn phải đặc biệt chú ý trong khai báo operator phía trên:

  • PhanSo là kiểu giá trị trả về sau khi thực hiện toán tử
  • const PhanSo& ở đây là kiểu giá trị nhận vào

Bạn thử sửa PhanSo& operator += (const PhanSo&); thành void operator += (const PhanSo&); rồi biên dịch và chạy thử xem, và suy nghĩ thử PhanSo& trả về để làm gì và khi nào nó cần thiết

Lau Cr Pắp viết 19:09 ngày 30/09/2018

PhanSo operator + (const PhanSo&); //1PhanSo& operator += (const PhanSo&); //2

PhanSo và PhanSo & về bản chất là giống nhau đều báo cho hàm (ở đây là toán tử operator) biết kiểu giá trị trả về là PhanSo
Vậy sự khác biệt của & là j, không lẽ viết vào cho code trông có vẻ pro hơn (ý kiến cá nhân: cái gì mà có & thì trông rất pro). Thực ra dùng than chiếu (&) để tránh việc gọi lại copy constructor. Nếu trong class phân số kia mà không có con trỏ thì PhanSo hoặc PhanSo & không có khác biệt nhiều. Ngược lại thì đó là một vấn đề hết sức đau đầu khi tìm lỗi.
P/S có j sai sót xin mọi người lượng thứ

Bùi Trung Thông viết 19:08 ngày 30/09/2018

Lý do làm a thay đổi là phép gán = thông operator=

ý bạn là chức năng mặc định của dấu = phải không (không phải overload lại)

suy nghĩ thử PhanSo& trả về để làm gì và khi nào nó cần thiết

theo mình biết là trả về tham chiếu phân số luôn , thông qua con trỏ this chẳng hạn, cần thiết vì mình đang update lại chính nó mà.
cảm ơn comment của bạn, giúp mình hiểu được chút vấn đề.

Bùi Trung Thông viết 19:06 ngày 30/09/2018

Thực ra dùng than chiếu (&) để tránh việc gọi lại copy constructor.

bạn giải thích rõ hơn chỗ này cho mình hiểu được không ?

BaoLe viết 19:05 ngày 30/09/2018
PhanSo operator +(const PhanSo&)

khi bạn return thì sẽ trả về một bản sao. Cụ thể:

PhanSo operator +(const PhanSo&)
{
    PhanSo KetQua;
    ...................................
    return KetQua;
}

Lúc này sẽ trả về bản sao của KetQua.
Ngược lại nếu là:

PhanSo& operator + (const PhanSo&)

Thì sẽ trả về chính cái KetQua

Bùi Trung Thông viết 19:00 ngày 30/09/2018

mình vẫn không hiểu, theo mình biết thì KetQua khai báo bên trong phương thức này thôi, ra ngoài rồi nó cũng tự huỷ, thế thì làm sao nó trả về chính KetQua(trường hợp &) trong khi nếu nó đã gọi destructor.

BaoLe viết 19:02 ngày 30/09/2018

Nó chỉ hủy sau khi thực hiện xong lệnh return.

Bùi Trung Thông viết 19:05 ngày 30/09/2018

Nó chỉ hủy sau khi thực hiện xong lệnh return.

mình nghĩ nếu trả về chính địa chỉ của đối tượng gọi phương thức thì được, còn nếu là đối tượng KetQua như bạn thì lấy đâu vùng nhớ để hoạt động sau khi trả về.

Tran Huan viết 19:03 ngày 30/09/2018

Trường hợp trả về Reference mà BaoLe nêu lên thì Object đã bị hủy sau khi trả về nên reference trả về trỏ vào vùng nhớ đã được hủy. Tuyệt đối không nên sử dụng phương cách này!

Để hạn chế việc copy và tạo object mới khi thực hiện các toán tử không làm thay đổi giá trị của object nhận vào thì người ta thường dùng const Class& object;

Xem thử Implement toán tử +=:

PhanSo& operator += (const PhanSo& b)
{
    this.member += b.member;
    return *this;
}

Ở đây đối tượng trả về là chính bản thân nó nên hoàn toàn có thể sử dung reference, hơn nữa để có thể tiếp
tục sử dụng cho toán tử tiếp theo thì bắt buộc phải sử dụng reference trả về ở đây

VD: PhanSo a; a += b += c;

Để hiểu rõ hơn thì các bạn có thể thay kiểu trả về là PhanSo thay vì PhanSo& và chạy với ví dụ trên so sánh kết quả thử xem

Bùi Trung Thông viết 19:03 ngày 30/09/2018

trường hợp dùng tham chiếu:

VD: PhanSo a; a += b += c;

cho em hỏi chỗ này có nghĩa là khi b+=c nó trả về tham chiếu của b, sau đó nó lấy tham chiếu đó (bản thân b) và tiếp tục với a+=b và trả về tham chiểu của a đúng không anh?

còn trường hợp không dùng tham chiếu thì em không hiểu được tại sao lại cộng liên tiếp như vậy được ?
cảm ơn anh.

Tran Huan viết 19:10 ngày 30/09/2018

Chính xác rồi bạn. Lúc dùng tham chiếu sẽ giảm số lượng copy contructor được gọi, do không cần tạo ra các đối tượng mới nữa.

Nhưng xét ví dụ này thử: (a += b) += c;

Ở đây nó thực hiện a += b trước sao đó tiếp tục cộng thêm c

Nếu dùng tham chiếu thì kết quả của a là: a = a + b +c;
Nếu dùng tham trị thì kết quả: a = a + b; vì phần (a += b) thay đổi giá trị của a và return về một đối tượng tạm thời đối tượng này thực hiên phép toán temp += c; sau đó temp bị huỷ

Bùi Trung Thông viết 19:09 ngày 30/09/2018

quá hay luôn. cảm ơn anh

Bài liên quan
0