Item 28 Meaning of Pointer Comparison trong C++ Common Knowledge: Essential Intermediate Programming) giải thích sự quan trọng của con trỏ đối tượng trong C++:
Trong C++, một đối tượng có thể có nhiều, địa chỉ hợp lệ, và con trỏ so sánh không phải là một câu hỏi về địa chỉ. Đó là một câu hỏi về nhận dạng đối tượng.
Hãy nhìn vào các mã:
class A{};
class B{};
class C: public A, public B {};
C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;
class C
xuất phát từ cả hai class A
và class B
, vì vậy class C
là cả class A
và class B
. đối tượng C c
có 3 địa chỉ hợp lệ: địa chỉ cho class A
, class B
và class C
. Việc thực hiện phụ thuộc vào trình biên dịch, vì vậy bạn không thể giả định cách bố trí bộ nhớ của class C
, và nó có thể như thế này:
---------- <- pc (0x7ffe7d10e1e0)
| |
---------- <- pa (0x7ffe7d10e1e4)
| A data |
---------- <- pb (0x7ffe7d10e1e8)
| B data |
----------
| C data |
----------
Trong trường hợp trên, mặc dù giá trị địa chỉ của pc
, pa
và pb
không giống nhau, tất cả chúng đều đề cập đến cùng một đối tượng (c
), do đó trình biên dịch phải đảm bảo rằng pc
so sánh bằng cả hai pa
và pb
, tức là, pc == pa
và pc == pb
. Trình biên dịch hoàn thành việc so sánh này bằng cách điều chỉnh giá trị của một trong các con trỏ được so sánh với độ lệch thích hợp. Ví dụ:
pc == pa
được phiên dịch sang:
pc ? ((uintptr_t)pc + 4 == (uintptr_t)pa) : (pa == 0)
Trong số những thứ khác, vì A
và B
không có quan hệ thừa kế, chúng ta không thể so sánh pa
và pb
trực tiếp.
Đối với câu hỏi của bạn:
(1) does pa point to a valid A object?
(2) does pb point to a valid B object?
Yes, refer the above diagram.
(3) pc == (C*) pa ?
(4) pc == (C*) pb ?
Yes, No need to add (C*).
(5) does pa == pb ?
No. We can't compare them.
những gì bạn có nghĩa là bởi ==? Rõ ràng, các địa chỉ giống nhau. –
Các địa chỉ không phải là necesarrily giống nhau. –
Trong một triển khai đa thừa kế (virtual) mà tôi đã thấy, một số offset được thêm vào địa chỉ cơ sở của đối tượng lớp dẫn xuất để truy cập vào các thuộc tính và phương thức của B. Tuy nhiên điều này không hiển thị cho người dùng khi trình biên dịch thao tác nội bộ. Do đó trong chương trình của bạn, bạn vẫn có thể thấy địa chỉ của A, B và C giống nhau. – mukeshkumar