Có tốt không khi gửi đối tượng được phân bổ stack như một tham số con trỏ tới một số chức năng khác?Có tốt không khi gửi đối tượng được phân bổ stack như một tham số con trỏ tới một số chức năng khác?
Có tốt không khi gửi đối tượng được phân bổ stack như một tham số con trỏ tới một số chức năng khác?
Trả lời
Có, nhưng thành ngữ C++ phổ biến hơn trong trường hợp này là sử dụng tham chiếu (và có thể là một tham chiếu const) thay vì một con trỏ. Vì vậy, thay vì
void foo(sometype * p) {
p->func();
}
bạn viết:
void foo(sometype & p) {
p.func();
}
này có ưu điểm là bạn không cần phải dereference các đối tượng trong người gọi:
void afunc() {
sometype t;
foo(t);
}
và cũng đưa ra một tiềm thức gợi ý cho người đọc rằng bạn không có ý định thực hiện chức năng sở hữu đối tượng.
Nếu bạn chắc chắn rằng cuộc gọi là đồng bộ thì nó là hoàn toàn hợp lệ để gửi địa chỉ của đối tượng được cấp phát chồng lên chức năng. Trong trường hợp cuộc gọi không đồng bộ (tức là chức năng bạn gọi là chuyển con trỏ đến một luồng khác) thì nó chắc chắn sẽ tạo ra các vấn đề khi bạn có thể thử truy cập địa chỉ bộ nhớ từ chuỗi khác ngay cả sau khi đối tượng được cấp phát được định sẵn.
Khá giả định, như với ngôn ngữ C hoặc C++ đơn giản, người ta không thể gọi bất kỳ hàm nào không đồng bộ. Assafs trả lời là gần gũi hơn với cuộc sống hàng ngày. – lothar
lothar - làm thế nào về ngã ba()? Bất kỳ chương trình không tầm thường nào vẫn chạy trong một chuỗi đơn lẻ là một con khủng long. Modding này lên. – MaxVT
@MaxVT Gọi ngã ba là không có nghĩa là một phương pháp để gọi không đồng bộ một chức năng, toàn bộ quá trình của bạn được nhân đôi (bao gồm tất cả dữ liệu của nó). – lothar
Miễn là chức năng nhận không giả định rằng nó có được quyền sở hữu tài nguyên (và cố gắng giải phóng nó), chắc chắn. Một tham chiếu có thể là một ý tưởng tốt hơn.
Hoàn toàn phù hợp cho cuộc gọi chức năng đồng bộ. Nếu cuộc gọi không đồng bộ, nó có thể dẫn đến sự cố khi đối tượng ngăn xếp bị xóa khi nó nằm ngoài phạm vi.
Bạn nên cẩn thận không lưu trữ con trỏ đó để sử dụng thêm. Ví dụ:
void store(int* param) {
// Store pointer in some global storage for further use
global_storage.add_param(param);
}
void func() {
int test_var = 5;
store(&test_var); // Pass the pointer to the global storage
}
// At this point stack object test_var will be destroyed
// Global storage contains a pointer, that points to some garbage
Chắc chắn là hợp lệ, nhưng với nhiều lưu ý. Dưới đây là những điều cần lưu ý nhất (một số đã được đề cập bởi những người khác, một số thì không.)
- Con trỏ trong chính nó có thể ngụ ý rằng quyền sở hữu tài nguyên được chuyển đến tên gọi (tức là họ phải giải phóng nó sau khi sử dụng) . Ở đây, một tham chiếu được đặt ra. Trong nhiều trường hợp, chức năng mà bạn cần gọi đã được xác định và bạn không thể thay đổi nó, bạn phải nghiên cứu hành vi của nó và đảm bảo nó không cho rằng nó sẽ sở hữu đối tượng, lưu trữ nó tĩnh hoặc sao chép nó ở nơi khác.
- Nếu chức năng bạn đang gọi cần có một con trỏ rỗng để biểu thị sự vắng mặt của tham số đã nói, bạn sẽ không có lựa chọn sử dụng tham chiếu.
- Cuộc gọi không đồng bộ hoàn toàn là không có (trừ khi, tất nhiên, bạn chặn cho đến khi chúng được thực hiện bằng cách sử dụng đối tượng địa phương của bạn và sau đó quay trở lại).
- Chức năng được gọi sẽ không bao giờ trong bất kỳ sự kiện nào vượt quá kích thước của đối tượng được đề cập, điều này sẽ phá hủy ngăn xếp của bạn và gần như chắc chắn làm hỏng chương trình của bạn!
- Gọi một hàm có khả năng truy cập byte vượt quá kích thước của đối tượng có thể là trách nhiệm bảo mật. Trong chứng thư, đây là phương pháp phổ biến nhất để đột nhập vào các hệ thống an toàn. Điều này được gọi là tràn bộ đệm.(ngoài phạm vi câu hỏi của bạn, nhưng bạn có thể đọc thêm here và here)
- 1. Tham số chức năng: Con trỏ tới mảng đối tượng
- 2. Con trỏ trỏ tới mảng như tham số chức năng
- 3. Con trỏ tới các đối tượng được phân bổ tĩnh
- 4. Vượt qua con trỏ tới mẫu-chức năng như đối số chức năng?
- 5. Con trỏ của một số chức năng
- 6. chức năng như tham số vs con trỏ hàm như tham số
- 7. Chuyển một con trỏ tới hàm thành viên của lớp như một tham số
- 8. Trả về một đối tượng struct lớn theo giá trị hoặc con trỏ tới phân bổ động trên C++
- 9. C++ * vs [] như một tham số chức năng
- 10. Đi qua một tham số như một con trỏ trong Javascript
- 11. con trỏ golang trên con trỏ như chức năng thông số
- 12. con trỏ hàm chức năng khác nhau với các đối số khác nhau trong C
- 13. Con trỏ 'này' có khác với con trỏ của đối tượng không?
- 14. Gán con trỏ cho một hàm địa chỉ của con trỏ tới đối tượng hàm
- 15. Node.js gửi một đối tượng có định nghĩa chức năng tới chuỗi công việc
- 16. Passing C++ con trỏ như là đối số vào Cython chức năng
- 17. Thông số chức năng: Sao chép hoặc con trỏ?
- 18. Chuyển chức năng như một tham số trong java
- 19. Ruby - Có thể truyền một khối như một tham số như một khối thực tế cho một chức năng khác?
- 20. Con trỏ trỏ tới con trỏ số học
- 21. C: Con trỏ trỏ tới nội tuyến chức năng
- 22. sự khác biệt giữa một con trỏ và tham số tham chiếu?
- 23. Đối số mảng có được chuyển đến một hàm không phải là một con trỏ không?
- 24. Tính năng unboxing chỉ trả về một con trỏ tới giá trị trong đối tượng được đóng hộp trên heap?
- 25. Đi qua một chức năng như tham số
- 26. Gọi chức năng đối tượng thông qua con trỏ đối tượng
- 27. đối số chức năng
- 28. Chức năng trả về một đối tượng có loại được chỉ định trong đối số
- 29. nhiều chức năng có cùng tên nhưng các loại đối số khác nhau như tham số mẫu
- 30. python ctypes gửi con trỏ tới cấu trúc làm tham số cho thư viện gốc
"và có thể là tham chiếu const": const & s là tuyệt vời và nên được sử dụng bất cứ khi nào có thể, nhưng bất cứ khi nào hàm có ý định thay đổi giá trị của tham số, bạn phải chuyển một con trỏ chứ không phải tham chiếu. thông số. Quyền sở hữu trí tuệ phải được ghi lại đầy đủ – Tom
+1 cho câu trả lời của Tom –