2009-04-13 18 views

Trả lời

12

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.

+3

"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

+0

+1 cho câu trả lời của Tom –

10

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.

+0

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

+0

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

+0

@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

6

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.

2

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.

2

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 
1

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 herehere)
Các vấn đề liên quan