Câu trả lời:
Hai biểu thức sau là tương đương:
a->b
(*a).b
(tùy thuộc vào quá tải toán tử, như Konrad đề cập, nhưng điều đó là bất thường).
a[0].b
thay vì (*a).b
. Nhưng nó sẽ không được cấu trúc đúng như vậy.
a->b
nói chung là một từ đồng nghĩa với (*a).b
. Các dấu ngoặc đơn ở đây là cần thiết vì độ bền liên kết của các toán tử *
và .
: *a.b
sẽ không hoạt động vì .
liên kết mạnh hơn và được thực thi trước. Do đó, điều này tương đương với *(a.b)
.
Tuy nhiên, hãy cẩn thận với quá tải: Vì cả hai ->
và *
có thể bị quá tải, ý nghĩa của chúng có thể khác nhau đáng kể.
binding strength
bạn nghĩa là ưu tiên toán tử? nếu không sự khác biệt giữa hai là gì?
Ngôn ngữ C ++ định nghĩa toán tử mũi tên ( ->
) là một từ đồng nghĩa để tham chiếu đến một con trỏ và sau đó sử dụng .
-operator trên địa chỉ đó.
Ví dụ:
Nếu bạn có một một đối tượng, anObject
và một con trỏ, aPointer
:
SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;
Để có thể sử dụng một trong các phương thức đối tượng, bạn bỏ qua con trỏ và thực hiện một lệnh gọi phương thức trên địa chỉ đó:
(*aPointer).method();
Có thể viết bằng toán tử mũi tên:
aPointer->method();
Lý do chính của sự tồn tại của toán tử mũi tên là nó làm ngắn việc nhập một tác vụ rất phổ biến và nó cũng dễ quên dấu ngoặc đơn xung quanh hội nghị của con trỏ. Nếu bạn quên dấu ngoặc đơn, toán tử.-Sẽ liên kết mạnh hơn sau đó là * -operator và làm cho ví dụ của chúng ta thực thi như sau:
*(aPointer.method()); // Not our intention!
Một số câu trả lời khác cũng đã đề cập đến cả hai toán tử C ++ có thể bị quá tải và nó không phổ biến.
new SomeClass()
trả về một con trỏ ( SomeClass *
), không phải SomeClass
đối tượng. Và bạn bắt đầu với việc khai báo anObject
và aPointer
nhưng bạn đang sử dụng p
sau đó.
Trong C ++ 0x, toán tử có nghĩa thứ hai, cho biết kiểu trả về của một hàm hoặc biểu thức lambda
auto f() -> int; // "->" means "returns ..."
::
thực sự là một toán tử, giống như .
hoặc ->
, và được gọi là "toán tử phân giải phạm vi" trong tiêu chuẩn.
->
được sử dụng khi truy cập dữ liệu mà bạn có con trỏ tới.
Ví dụ: bạn có thể tạo một con trỏ ptr tới biến kiểu int intVar như sau:
int* prt = &intVar;
Sau đó, bạn có thể sử dụng một hàm, chẳng hạn như foo, trên nó chỉ bằng cách tham chiếu đến con trỏ đó - để gọi hàm trên biến mà con trỏ trỏ đến, thay vì giá trị số của vị trí bộ nhớ của biến đó:
(*ptr).foo();
Nếu không có dấu ngoặc ở đây, trình biên dịch sẽ hiểu điều này là *(ptr.foo())
do sự ưu tiên của toán tử không phải là điều chúng ta muốn.
Điều này thực sự cũng giống như gõ
ptr->foo();
Như là các ->
tham chiếu mà con trỏ, và do đó gọi hàm foo()
trên biến mà con trỏ đang trỏ tới cho chúng ta.
Tương tự, chúng ta có thể sử dụng ->
để truy cập hoặc đặt thành viên của một lớp:
myClass* ptr = &myClassMember;
ptr->myClassVar = 2;
->
toán tử nạp chồng cho một số kiểu trình vòng lặp nên bạn phải sử dụng*.
. Nhiều thư viện định nghĩa chúng không nhất quán. Thực sự trở nên khó chịu khi bạn làm việc với các mẫu và không biết loại chính xác.