Thắc mắc khi sử dụng con trỏ this trong C++
Chào anh chị em và các bạn trên diễn đàn, em mới học C++ , anh giảng viên có cho 1 ví dụ về cách sử dụng con trỏ this mà em nghĩ mãi vẫn chưa thực sự hiểu nên em muốn mọi người giúp em hiểu rõ bản chất của nó ạ .
Em muốn hỏi là :
-
Thứ nhất, ở Phương thức RutGon , khi không sử dụng con trỏ this để thực thi phương thức RutGon mà anh gv lại tạo 1 đối tượng ps , sau đó làm việc trên đối tượng ps đó. Thì khi return ps;
anh ấy giảng đoạn này là Giá trị của this->TuSo và this->MauSo không hề thay đổi .
Và khi xuống dưới hàm main , để có thể sử dụng hàm RutGon và hàm Xuat và rút gọn đi giá trị được nhập vào từ hàm nhập thì phải tạo thêm 1 đối tượng ps2 để nhận cái return ps; của hàm RutGon trên kia thì code mới chạy
em chưa hiểu cái đoạn return ps và xuống dưới tạo thêm ps2 để đón giá trị ps được return ạ
và em muốn hỏi là ở phương thức RutGon thì return ps; là trả về cái gì ạ ? ( anh gv nói là trả về 1 cái đã thay đổi giá trị sau khi được rút gọn , nhưng " cái đó " là cái gì ạ ?)
nếu đã trả về cái đã được thay đổi giá trị sau khi rút gọn tử số và mẫu số thì tại sao lại phải sử dụng ps2 ở hàm main ạ ??? -
em muốn hỏi câu lệnh này có nghĩa gì ạ : a = abs(ps.TuSo);
em biết là em hỏi khá rắc rối vì thực sự em thấy đoạn ps và ps2 phức tạp quá ạ , nhưung mong mọi người giúp em , không hiểu được chắc đêm nay em mất ngủ :(((
đây là code ạ
#include <iostream>
using namespace std;
// Con trỏ this
// Con trỏ this tham chiếu đến đối tượng đang gọi hàm thành phần
class PhanSo{
int TuSo, MauSo;
public:
PhanSo RutGon();
void Nhap();
void Xuat();
};
// Cách dùng thứ 1 của Con trỏ this : trỏ(tham chiếu) đến các thành phần của class hiện tại
void PhanSo::Nhap(){
cout<<"
Nhap tu so : ";
//cin>>TuSo;
cin>>this->TuSo;
cout<<"
Nhap mau so : ";
//cin>>MauSo;
cin>>this->MauSo;
}
void PhanSo::Xuat(){
cout<<this->TuSo<<"/"<<this->MauSo;
}
// Không dùng This nữa mà tạo đối tượng PS
PhanSo PhanSo::RutGon(){
int a,b;
PhanSo ps;
ps.TuSo=this->TuSo;
ps.MauSo=this->MauSo;
//Hàm tìm UCLN thông thường
a = abs(ps.TuSo);
b = abs(ps.MauSo);
while(a!=b){
if(a>b){
a=a-b;
}
else{
b=b-a;
}
}
ps.TuSo=TuSo/a;
ps.MauSo=MauSo/a;
// Giá trị của this->TuSo và this->MauSo không hề thay đổi
return ps; // Trả về giá trị của cái Class hiện tại
}
int main(){
PhanSo ps,ps2;
ps.Nhap();
ps2=ps.RutGon(); // ps.TuSo và ps.MauSo không hề thay đổi, chỉ trả về 1 ps đã thay đổi
//ps hoàn toàn không thay đổi
ps2.Xuat();
return 0;
}
lấy giá trị tuyệt đối
Tiếp theo là doituong.phuongthuc thì this.-> là thuộc tính của thằng doituong
ps2=ps.RuGon() trong phương thức RutGon khong dùng this nên ps ko thay đỏi gì, tạo ra 1 thắng ps rồi gán gt cho nó để return nên ps2 sẽ mang giá trị ps đấy
anh ơi , khi return ps;
thì nó sẽ trả lại giá trị của class hiện tại . Giá trị đó chính là giá trị của TuSo và MauSo đúng không ạ ?
nó trả về gt của thằng PS chứ không phải class hiện tại(PS là 1 class mới)
Theo như mình hiểu thì bạn đang thắc mắc về cách hoạt động của từ khóa return
Bạn cứ tưởng tượng khi khai báo
PhanSo ps, ps2
thìps
vàps2
là hai cái thùng trong máy tính, mỗi thùng chứa 2 tờ giấy làTuSo
vàMauSo
, 2 tờ giấy này không ghi gì cả. Sau đó bạn gọi phương thứcps.Nhap()
thì máy tính sẽ bắt đầu ghi dữ liệu vào 2 tờ giấyTuSo
vàMauSo
trong thùngps
.Tiếp theo khi bạn gọi phương thức
ps.RutGon()
, bên trong phương thức này lại có 1 khai báo khác làPhanSo ps
thì máy tính lại tạo một cái thùng có 2 tờ giấy trắngTuSo
vàMauSo
khác và cái thùngps
này không liên quan gì đến cáips
được tạo ra ở hàmmain
cả, bản thân cáips
được tạo trongRutGon()
sẽ bị máy tính xóa đi sau khi kết thúc lệnhreturn
. Ở đây mình gọi tắt làpsRutGon
vàps
để dễ phân biệt một tí nhé.Bên trong phương thức RutGon() bạn có gọi
ps.TuSo=this->TuSo;
ps.MauSo=this->MauSo;
Hai dòng này tương đương với:
psRutGon.TuSo = ps->TuSo;
psRutGon.MauSo = ps->MauSo;
(mình chỉ viết như vậy cho dễ hiểu chứ ghi như thế là sai nhé)
Tức là 2 tờ giấy
TuSo
vàMauSo
bên trong cái thùngpsRutGon
được tạo ra bên trong phương thứcRutGon()
giờ đây có giá trị bằng với 2 tờ giấy trong thùngps
ở hàm main, rồi sau đó là quá trình rút gọn phân số bla bla…Sau khi đã rút gọn xong, câu lệnh cuối cùng là
return ps;
bản thân máy tính sẽ không xóa cái thùngpsRutGon
như mình nói ở trên mà nó chỉ quên đi cái thùng đó thôi, còn cái thùng thực chất vẫn nằm đâu đó trong máy tính. Do đó bạn phải có câu lệnhps2 = ps.RutGon()
để lưu lại thông tin của cái thùng đó trongps2
.Đến đây là hiểu rồi chứ?
Lưu ý: mình không biết C++ đến bây giờ có cho phép hay không nhưng đoạn gán dữ liệu theo mình nhớ phải là
ps.TuSo = this.TuSo;
ps.MauSo = this.MauSo;
Toán tử
->
chỉ dành cho con trỏ, nếu muốn dùng toán tử này thì bạn phải khai báo làPhanSo *ps
trong hàmmain
.Update: mình nhầm, tuy khai báo không phải là con trỏ nhưng this là một con trỏ đặc biệt nên vẫn phải dùng toán tử
->
nhé.Còn hàm
abs()
là lấy giá trị tuyệt đối thôi, không có gì phức tạp. Vdabs(-5) = 5; abs(5) = 5
…Nhiều khi lập trình viên cũng nên biết qua tiếng Anh và cách tra cứu hàm nhỉ.
abs = absolute, nghĩa là lấy giá trị tuyệt đối (tên hàm thường hay rút gọn thành 3 chữ)
Và theo thiển ý của mình, cũng nên đặt tên hàm / comment bằng tiếng Anh cho quen. Dùng tiếng Việt sau phát triển sản phẩm, những người maintain không phải dev Việt sẽ không hiểu gì luôn.
C++ object thì phải dùng . chứ (chưa gõ lại nhưng chắc code này không chạy).
-> chỉ dành cho pointer.
em cám ơn các anh rất nhiều ạ , em đi học cả ngày giờ mới về nhà , qua sự giúp đỡ của các anh em đã hiểu thêm được phần nào rồi ạ