Bản chất của phương thức trong class

Em muốn in địa chỉ của phương thức print trong class Test của từng đối tượng như vầy không biết đúng không?

Nếu đúng thì tại sao 2 đối tượng A,B lại dùng chung phương thức (về mặt tổ chức trên bộ nhớ) vậy ạ? Cái em in ra có phải là địa chỉ của phương thức print của đối tượng A,B hay chỉ là địa chỉ mà phương thức print (của class) nằm trên bộ nhớ?
(Em nghĩ là nó dùng chung cho tiết kiệm bộ nhớ, ko biết đúng ko ^^ )

Phương thức thì dùng chung, chỉ có các trường dữ liệu là độc lập.

Bạn cũng thấy đấy, bạn gọi Test::print chứ không phải A::print hay B::print.

4 Likes

Sự thật là vậy. Phương thức sẽ vẫn là Phương thức trong class. trong 1 sự việc để làm chính xác địa chỉ hàm. ta sẽ xét trường hợp sau để sạch sẽ

class A
{
 A(int a){x=a;}
 int x;
 Foo()
 {
 printf("%d\n",x);
 }
}
void main()
{
A test1(5);test1.foo();
A test2(1);test2.foo();
}

lúc này ta sẽ có kết quả khác nhau đúng không. vì chúng khác nhau con trỏ “this” (nếu DEBUG thông lệ sẽ truyền vào ECX trong ASSEMBLY)
thực sự khi gọi hàm thì ngầm định class sẽ truyền địa chỉ con trỏ this như 1 biến ngầm hãy để ý sự thực tập sau khi sửa lại hàm foo()

class A
{
 A(int a){x=a;}
 int x;
 Foo()
 {
 printf("%d from%x\n",x,(unsigned int)this);
 }
}
4 Likes

E vẫn chưa rõ câu này lắm! sẵn cho e hỏi con trỏ this được lưu ở đâu? Có phải nó cũng giống như phương thức là được dùng chung không ạ?
p/s: e mới đọc trên stackoverflow nói là this pointer thực sự là 1 rvalue (không thể lấy địa chỉ) nên không nhất thiết nó chiếm bộ nhớ là sao ạ?

Do nó ko cần có slot nên ko thể làm lvalue thì đúng hơn :smiley: sau này có [l|gl|x|r|pr]value nữa. (C++11)

Quy định về this phần overload resolution, 12.3.1 [over.match.funcs]

The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.

5 Likes

Đọc thêm bài dưới để hiểu hơn về this nha bạn, tuy là Java nhưng với C++ thì cũng gần như là vậy. :slight_smile:

3 Likes

Không hẳn vì C++ chỉ có asm làm trung gian thôi :smiley: chứ ko có VM.

4 Likes

Vậy em mới để cái này, mà kể ra nói gần như là vậy cũng chưa đúng lắm. K biết nói sao nữa. :sweat_smile:

2 Likes

Vậy cho e hỏi là trong 1 chương trình có thể có nhiều this không hay chỉ có 1 this , sau đó nếu đối tượng nào cần sử dụng thì this sẽ mang địa chỉ của đối tượng đó? (Ý e là this trên bộ nhớ/ thanh ghi)

Mình cũng không chắc về vấn đề này (không rành C++ lắm). Nhưng theo mình nghĩ thì sẽ là có nhiều this. Và vòng đời của mỗi this sẽ được sinh ra khi một phương thức được gọi, và cũng mất đi sau khi thực thi song. :slight_smile:

2 Likes

Nó như không khí ấy mà :smiley: sao nói 1 hay nhiều được. #deep

4 Likes

:joy::joy::joy: càng hỏi e lại càng thắc mắc. Sao nghe nó hư vô quá nhỉ :rofl:
Cho e hỏi r làm sao cái this đó nó nhận ra nó đag là ai ta? có cái gì truyền cho nó địa chỉ của đối tượng ko?

Thì this là tham số ẩn mà :smiley: như các reply trước đã nêu.

Và hệ quả là

// C++11
struct Fraction {
   int num; unsigned int denom;
   Fraction operator+(Fraction&);
   Fraction& operator++();
};
#include <iostream>
int main() {
   Fraction f{1, 2}, g{3, 4};
   std::cout << (++(f+g)).num; // <---- what
}
5 Likes

Thanks mọi người :joy:
muốn hiểu sau hơn chắc phải đọc hợp ngữ của nó :cry::cry::cry:

Theo mình thấy là như vậy:
Khi ở bên trong đối tượng và cần truy cập địa chỉ của chính nó thì người ta định danh 1 con trỏ là this.

2 Likes

Cũng không hẳn là em cần phải học ASM, vì khi biên dịch ra ASM thì nó chuyển tất cả function, function pointer thành lệnh jump mất tiêu rồi, có mò cũng không biết, chưa kể dính tới bộ optimizer nữa.

Về cách chuyển từ method của OOP sang function hay procedure của lập trình thủ tục về ý tưởng là giống nhau, (kể C++ cũng thế), nhưng mỗi ngôn ngữ sẽ có cách làm hơi khác tí xíu.

Về C++, có 2 chỗ khác biệt, tất cả function và function pointer đều có address dưới dạng mã nhị phân, và 1 bảng gọi là symbol table sẽ trỏ tới các address này. Symbol table về lí thuyết sẽ lưu tất cả các token trong ngôn ngữ, từ biến, số, function, =, if, white, +, *,… nhưng thường nó chỉ lưu biến và function. Thay vì compiler chuyển từ ngôn ngữ C++ sang một ngôn ngữ đơn giản hơn (như C) thì nó sẽ chuyển tất cả method trong class, tất cả function sang address, và có các token tương ứng trong symbol table trỏ tới từng address.

Khác biệt thứ 2, là xử lí con trỏ this, vì C++ có virtual function, nên có 1 bảng gọi là vtable để compiler biết là nên chọn method nào khi có nhiều virtual function. Sau khi nó chọn method phù hợp, compiler sẽ lấy address của method đó, rồi bỏ this vào tham số đầu tiên như thường. Khi chuyển sang ASM, thì các bước vtable và gọi hàm nó toàn cho JUMP qua JUMP lại thì đọc hiểu thế nào được.


Mà cái chỗ xử lí this cũng rắc rối cả ra, Python, JavaScript, Java, C++ mỗi thằng mỗi kiểu, chưa thống nhất được.

4 Likes

Tham khảo thêm cái này hay nè: https://tradahacking.vn/dịch-ngược-chương-trình-hướng-đối-tượng-c49198c364e2

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?