2013-02-11 39 views
38

Làm cách nào để quyết định xem tôi có cần addressof(x) thay vì &x khi lấy địa chỉ của một đối tượng không?Khi nào sử dụng địa chỉ (x) thay vì & x?


Có vẻ như câu hỏi là khó hiểu, vì vậy làm rõ là theo thứ tự:

addressof hiển nhiên bỏ qua địa chỉ-of quá tải toán tử. Tôi đã biết điều đó.

Điều tôi muốn biết là:
Làm cách nào để biết đó là điều tôi thực sự muốn làm? (Đặc biệt khi bên trong một mẫu, vv)

Có một số loại "quy tắc" giúp tôi tìm ra khi tôi cần addressof thay vì &?
Sau khi tất cả, cả hai đều trả về "địa chỉ của" đối tượng, vì vậy khi nào tôi sử dụng?

Trả lời

52

Bạn sử dụng std::addressof khi cần. Đáng buồn thay, "khi bạn phải" bao gồm bất cứ lúc nào bạn đang làm việc trong mã mẫu và muốn biến một loại không xác định T hoặc T& thành con trỏ trung thực với bộ nhớ của biến đó.Bởi vì ủy ban C++ ngu xuẩn cho phép quá tải toán tử tham chiếu (ít mục đích hợp pháp), người dùng có thể tạo mẫu của bạn với một số kiểu mà bạn không thể sử dụng toán tử tham chiếu để có được một con trỏ thực tế đến. std::addressof là một cách để làm việc xung quanh những người dùng sử dụng tính năng C++ đáng ngờ này để làm những gì ngôn ngữ nên được đảm bảo để làm việc để bắt đầu.

Tóm lại, đó là thư viện sửa lỗi cho ngôn ngữ ngu xuẩn. Sử dụng nó trong mã mẫu thay vì & nếu bạn muốn đảm bảo người dùng không thể phá vỡ mã của bạn. Nếu người dùng của bạn có thể tin cậy không sử dụng tính năng được hình thành này, thì bạn có thể sử dụng &.

+4

+1 câu trả lời hay nhất tôi đã nhìn thấy cho đến nay, giải thích tình hình rất tốt. – Mehrdad

+1

Những gì tôi thấy buồn cười là * một * lớp * * mong đợi * để quá tải địa chỉ, 'reference_wrapper', dường như không ... – Mehrdad

+1

@Mehrdad: Điều đó không làm tôi ngạc nhiên; cả 'reference_wrapper' và' addressof' đều đến từ Boost. AKA: những người biết nhiều nhất về sự nguy hiểm của tình trạng quá tải. –

5

Sử dụng nó khi bạn muốn biết địa chỉ thực của đối tượng và không phải là kết quả của quá tải địa chỉ operator&.

+0

Điều đó sẽ không đánh bại mục đích của người vận hành quá tải? – Mehrdad

+0

@Mehrdad Có thể - nhưng bạn có thể chọn xem bạn có muốn quá tải hay không. – nos

+0

@Mehrdad Nếu bạn tin tưởng tất cả mọi người để thực hiện tốt 'toán tử &' s. –

7

Nếu đó là loại do người dùng xác định với trạng thái đơn lẻ quá tải operator& và bạn muốn địa chỉ của nó, hãy sử dụng addressof.

Tôi muốn nói rằng bạn nên luôn sử dụng & vì, như bạn nói, nếu bạn không làm như vậy, nó sẽ đánh bại mục đích của quá tải. Trừ khi tất nhiên bạn làm điều gì đó có ý nghĩa với tình trạng quá tải, trong trường hợp bạn cần addressof (bên ngoài lớp học, bên trong bạn chỉ có thể sử dụng this), nhưng bạn phải rất chắc chắn về những gì bạn đang làm.

Dưới đây là - nếu muốn quá tải operator& bên ngoài lớp (bạn có thể), bạn phải sử dụng addressof trở lại địa chỉ, nếu không nó kết quả trong đệ quy vô hạn:

struct Class 
{ 
    virtual ~Class() {} 
    int x; 
}; 

void* operator&(const Class& x) 
{ 
    //return &x; <---- infinite recursion 
    return addressof(x) + 4; //I know this isn't safe 
          //but I also know the intrinsics of my compiler 
          //and platform to know this will actually return 
          //the address to the first data member 
} 

tôi biết điều này không an toàn.

+0

Nó sẽ không hoàn toàn đánh bại mục đích của các nhà điều hành quá tải mặc dù? Làm thế nào để tôi biết tôi có nên đánh bại nó hay không? – Mehrdad

+0

@Mehrdad xem chỉnh sửa. –

+0

Hmm, vì vậy đây là một tình huống mà trong đó tôi không thể * thậm chí sử dụng '&' ngay từ đầu, điều này làm cho câu hỏi được khắc phục! – Mehrdad

6

chỉ Ý kiến ​​của tôi:

Trừ khi bạn là một phần của đội ngũ thiết kế các lớp và giao diện của nó, không bao giờ. Cá nhân tôi chưa bao giờ thấy lý do chính đáng để quá tải toán tử đó. Nhưng nếu ai đó thiết kế một lớp có ý nghĩa, và giả định rằng lớp đó có nghĩa là để tiêu thụ công cộng (có nghĩa là, lớp không dành cho việc sử dụng nội bộ chỉ trong một thư viện cụ thể), tôi sẽ mong đợi lớp làm việc trong mã bình thường tự nhiên hy vọng rằng & có nghĩa là "địa chỉ". Nếu lớp quá tải toán tử không được thiết kế theo cách hợp lý, thì tôi sẽ không dùng lớp đó, thời gian. Bởi vì một trong hai lớp đó bị hỏng, hoặc nó không có nghĩa là được sử dụng bên ngoài thư viện mà nó là một phần của.

4

Sau khi tất cả, cả hai đều trả về "địa chỉ" của đối tượng, vậy khi nào tôi nên sử dụng?

Bạn hoàn toàn không đảm bảo rằng quá tải operator& là "địa chỉ" của đối tượng, có thể không phải vậy, hoặc tác giả lớp có thể sẽ không bận tâm quá tải. Họ có thể đã quá tải nó để trả lại một loại khác, hoặc thậm chí là trả lại void nếu họ đang cố gắng hết sức để ngăn chặn mọi người lấy địa chỉ của nó.

Nếu bạn muốn có một con trỏ đến một đối tượng mà sức mạnh đã quá tải & (ví dụ vì loại của nó là một tham số mẫu để bạn không biết) sau đó sử dụng một trong hai std::addressof hoặc tài liệu mẫu của bạn không hỗ trợ loại trong nước không trả lại địa chỉ thực của đối tượng làm đúng loại.

Các vấn đề liên quan