2011-01-04 26 views
7

Tôi đang phát triển mô phỏng tiến hóa Darwin. Vì lý do hiệu suất, nó được viết bằng C++. Các sim được đại diện bởi một thể hiện của thế giới. Các loài động vật được đại diện bởi các trường hợp của động vật, một đối tượng khá phức tạp. Thế giới có hai phương pháp quan trọng:Cách đúng để vạch trần một đối tượng sống ngắn phức tạp

animal_at(int i) 

evolve(int n). 

animal_at trả về một con trỏ thô không null cho trường hợp động vật đại diện cho động vật thứ i.
phát triển các tiến bộ mô phỏng có thể vô hiệu hóa bất kỳ con trỏ nào được trả về bởi animal_at. Tôi muốn làm cho sim và động vật dễ dàng truy cập từ bên ngoài. Tôi có các ràng buộc cụ thể về python, nhưng tôi đang xem xét việc học CORBA hoặc Ice để thực hiện một giao diện chung chung hơn. Vấn đề là làm thế nào tôi nên phơi bày động vật. Tôi có hai ý tưởng, không ai trong số đó cảm thấy thỏa đáng: 1) Viết lại mã một chút để sử dụng shared_ptr thay vì ptr thô và sử dụng phần mềm trung gian để hiểu ngữ nghĩa shared_ptr. 2) Tạo một "proxy lười sâu" có cấu trúc giống như Động vật. Các thành viên của nó sẽ là proxy cho các thành viên của Animal, đệ quy. animal_at sẽ thực sự được gọi trong giây phút trước khi đề cập đến dữ liệu thực tế - con trỏ sẽ được sử dụng và ngay lập tức bị ném đi. Điều này sẽ thực hiện ngữ nghĩa "thời điểm cuối cùng".

Tôi không thích 1) vì tôi sẽ phải giới thiệu trạng thái "zombie" của đối tượng, trông không phù hợp với tôi. Tôi không thích 2) vì mục đích duy nhất của proxy là triển khai ngữ nghĩa "khoảnh khắc cuối cùng".

Tôi đang tìm cách tự động không xâm nhập (sử dụng tạo mã) để đạt được điều này, bởi vì tôi không muốn làm mờ nghĩa của mã gốc. Có bất kỳ tên "chính thức" nào cho những gì tôi gọi là ngữ nghĩa "khoảnh khắc cuối cùng" không?

Trả lời

2

Có tùy chọn sử dụng boost :: weak_ptr. Bạn có thể vượt qua những xung quanh, họ phải sử dụng khóa() để có được shared_ptr cơ bản để họ có thể nhìn thấy nếu đối tượng không còn tồn tại.

Tuổi thọ của đối tượng chỉ được xác định bởi những nơi có shared_ptr. Do đó, phải có ít nhất một trong số đó trong suốt thời gian tồn tại của đối tượng, và bạn cần một cái trước khi bạn có thể tạo ra weak_ptr.

+0

Tôi sẽ xem xét kỹ hơn về tăng :: weak_ptr. Câu hỏi đặt ra là, điều này sẽ tương tác với CORBA như thế nào. Tôi không muốn học CORBA chỉ để tìm ra rằng "không, CORBA không hỗ trợ ngữ nghĩa cuối cùng". Cảm ơn vi đa trả lơi. –

+0

CORBA sử dụng tính tham chiếu của riêng nó với _var và không hỗ trợ khái niệm về một con trỏ yếu. Tôi nghĩ nếu bạn sử dụng một đối tượng không còn tồn tại ở phía máy chủ, bạn sẽ nhận được một ngoại lệ chứ không phải là một sự cố. Với CORBA khái niệm là toàn bộ máy chủ có thể đi xuống. Có một điều như là một ngoại lệ thoáng qua nơi máy chủ bị hỏng nhưng các đối tượng đã được tạo ra với "persistence" sao cho chúng sẽ tồn tại khi nó trở lại một lần nữa. – CashCow

1

Thứ nhất, bạn có thể xem xét xml-rpc thay vì CORBA làm phần mềm trung gian (sử dụng tiêu chuẩn hơn hiện nay).

Thứ hai, người dùng bên ngoài làm việc với dữ liệu được khắc phục. Họ gửi một tài liệu tham khảo marshalled trên middleware và mong đợi thông tin marshalled dựa trên yêu cầu và tham khảo của họ, vì vậy tôi không thấy làm thế nào điều này làm việc cùng với "cuối cùng" sementics và con trỏ. Bạn có thể giữ tất cả các động vật tạm thời của bạn, vì vậy người dùng bên ngoài có thể truy vấn chúng hoặc bạn có thể phải gửi rất nhiều ngoại lệ cho các động vật không tìm thấy. (hoặc bạn cho phép họ yêu cầu động vật "mới nhất")

+0

Vì lý do hiệu suất, tôi không có ý định marshall toàn bộ động vật. Tôi muốn người dùng bên ngoài có thể sửa đổi các thành viên riêng lẻ, thành viên của các thành viên, thậm chí có thể gọi các phương thức của các thành viên. Vml-rpc có phù hợp với giao tiếp "tự nhiên" với các đối tượng C++ không? –

+0

Nếu tham chiếu là chỉ số i của động vật (cùng một chỉ mục có thể tham chiếu đến các động vật khác nhau tại các thời điểm khác nhau), tôi phải tạo ra bản mẫu "proxy sâu" (tôi từ chối viết boilerplate bằng tay vì lý do ý thức hệ). Nếu tham chiếu bị ràng buộc với danh tính của đối tượng, phần máy chủ của phần mềm trung gian phải có khả năng xác định, cho dù đối tượng vẫn tồn tại (vì vậy nó nên sử dụng boost :: weak_ptr hoặc hơn). –

+0

xml-rpc không phải là "tự nhiên" như corba cho các đối tượng, nhưng trong các đối tượng cuối cùng cũng được truyền bởi đối tượng corba của nó tham chiếu, vì vậy mỗi thành viên, bạn sẽ cần một đối tượng cần phải được đăng ký/chưa đăng ký và tham chiếu của nó được thông qua. – stefaanv

1

Nếu chức năng animal_at trả về con trỏ có thể bị vô hiệu tại bất kỳ thời điểm nào trong tương lai, bạn có thể thử trả lại con trỏ thông minh (tôi muốn đề xuất một shared_ptr) trên một số weak_ptr tại đây, nhưng bạn có thể thoát khỏi con trỏ yếu nếu bạn cẩn thận với việc triển khai). Tuy nhiên, thay vì chỉ trực tiếp đến một đối tượng Animal, hãy trỏ đến đối tượng boost::optional<Animal>. Bằng cách đó, khi bạn làm mất hiệu lực con trỏ, bạn có thể đặt cờ invalid trên con trỏ và bất kỳ người dùng nào của đối tượng vừa bị vô hiệu hóa có khả năng kiểm tra xem họ có cần một con trỏ mới hay không.

+0

Cảm ơn bạn đã tăng :: gợi ý tùy chọn, tôi sẽ xem xét nó. –

+0

boost :: tùy chọn ở đây làm tương tự có thể được thực hiện bằng cách tăng :: weak_ptr. bạn lưu trữ tăng của bạn :: shared_ptr trong một số lưu trữ trung tâm và tăng trở lại :: weak_ptr từ animal_at. bạn chỉ cần phát hành shared_ptr để vô hiệu hóa nó. mỗi khi bạn muốn sử dụng weak_ptr bạn cần phải "khóa" nó: nếu (tăng :: shared_ptr animal = animal_weak_ptr.lock()) // con trỏ vẫn còn hợp lệ, sử dụng nó –

+0

@Robin Hood: Tôi đã nói rằng bạn có thể thực hiện cùng một điều với 'weak_ptr' là bạn đã cẩn thận về việc thực hiện. Sử dụng 'shared_ptr >' chỉ đơn giản là làm cho nó dễ đọc hơn một chút. Để kiểm tra xem con trỏ có còn hợp lệ (được điều khiển bởi đối tượng quản lý) hay không, một đoạn mã máy khách sẽ chỉ cần kiểm tra giá trị của 'p-> valid'. Như mọi khi, có nhiều hơn 1 cách để làm một con mèo ... –

1

Tôi không hiểu tại sao bạn muốn xuất con trỏ thay vì xuất một giao diện có vẻ chính xác là ngữ nghĩa "khoảnh khắc cuối cùng" mà bạn muốn. animal_at của bạn có thể trả về một đối tượng id, không phải con trỏ và giao diện sẽ cung cấp tất cả quyền truy cập bắt buộc cho đối tượng, như dosomething(id, params). Giao diện cũng có thể bao gồm các công cụ khóa/mở khóa để cho phép truy cập nguyên tử.

+0

Điểm tốt về truy cập nguyên tử. Bởi "proxy sâu" tôi có nghĩa là chính xác giao diện này. Các cuộc gọi sẽ trông giống như animal_proxy (5) .genome.genes [3] .codones [6] .dosomething (params) Tuy nhiên, tôi không biết bất kỳ công cụ nào để tự động tạo giao diện như vậy từ định nghĩa của Animal. –

+0

@Pavel: nếu mục tiêu của bạn là python, bạn đã xem xét một cái gì đó như SWIG? –

+0

Tôi đã có các ràng buộc python hoạt động (được tạo bằng Py ++), nhưng tôi muốn làm cho mô phỏng thành phần bất kỳ ngôn ngữ nào có thể dễ dàng giao tiếp với. –

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