2011-06-29 36 views
10

LƯU Ý: Tôi đã tìm thấy nguồn gốc của lỗi không thực sự liên quan đến shared_ptr, chỉ khéo léo ngụy trang như vậy trong thông báo lỗi. Do đó, dưới đây là cơ bản vô nghĩa (không phải là câu trả lời, họ đang sử dụng tốt)Chuyển tiếp shared_ptr mà không khai báo lớp

-

Tôi đang gặp một số vấn đề khi dùng một shared_ptr (tăng tại thời điểm này) mà tôi cần phải chỉ đơn giản là ra một con trỏ đến một chức năng khác. Sử dụng con trỏ nguyên gốc, chức năng can thiệp sẽ không cần phải có quyền truy cập vào định nghĩa của lớp, nhưng bằng cách sử dụng smart_ptr, nó xuất hiện. Có cách nào để tránh điều này?

Ví dụ, với một hàm mục tiêu:

void func(shared_ptr<SomeClass> const & obj) 

Các const & sẽ chăm sóc của một phần của vấn đề, nhưng nói rằng chúng ta có một lớp getter mà có được đối tượng đối với một số lớp khác, như:

shared_ptr<SomeClass> someClassInstance(); 

và đây là nơi mà tôi muốn chỉ đơn giản là lắp ráp các đối số và chuyển tiếp đến chức năng mục tiêu:

func(someClassInstance()); 

Với một con trỏ đơn giản, điểm này trong mã có thể chỉ đơn giản sử dụng một khai báo chuyển tiếp SomeClass, nhưng với một smart_ptr nó cần phải có định nghĩa đầy đủ (có lẽ là smart_ptr có thể cần phải xóa lớp).

Bây giờ, nếu someClassInstance phải trả lại const & vấn đề này sẽ thực sự biến mất khi mã can thiệp sẽ không sao chép bất kỳ đối tượng nào. Tuy nhiên, chức năng getter phải trả lại bản sao vì lý do an toàn chủ đề.

Có cách nào tôi có thể đạt được kiểu chuyển tiếp tham số con trỏ thông minh này mà không cần định nghĩa lớp? Đó là, tôi có thể sử dụng con trỏ thông minh trong cùng một thời trang như tôi sẽ là một con trỏ truyền thống trong trường hợp này.

-

CẬP NHẬT: Viết một thử nghiệm nhỏ câu trả lời là chính xác rằng một tuyên bố về phía trước là đủ. Tuy nhiên, GCC vẫn phàn nàn trong một tình huống. Tôi sẽ phải tìm ra chính xác những gì gây ra nó thất bại (trong tình huống cụ thể này).

Tôi có đóng câu hỏi này ngay bây giờ hay không?

+3

Tại sao bạn muốn chuyển một 'shared_ptr' theo tham chiếu? Có thể tham chiếu đến loại bê tông đủ không? Ngoài ra bạn có một số loại quan niệm sai lầm, 'shared_ptr' không yêu cầu định nghĩa đầy đủ của loại được truyền xung quanh, nó hoạt động với các loại không đầy đủ. –

+0

bạn không thể tạo mẫu 'func'? – Nim

+0

Tôi chỉ cố gắng vượt qua tham chiếu để tránh sự cố (nó giúp trong một số trường hợp). Tôi đoán tôi cần phải cô lập tình hình tốt hơn trong đó nó không hoạt động. –

Trả lời

14

Bạn cần ít nhất một tờ khai chuyển tiếp cho T cho mỗi lần đề cập đến shared_ptr<T>.

Chỉ khi bạn sử dụng đơn nhất shared_ptr::operator*shared_ptr::operator->, điều đầy đủ là cần thiết. Dưới mui xe, shared_ptr sử dụng một hỗn hợp của compiletime và đa hình thời gian chạy, làm cho điều này có thể. Xem thêm this question để tìm hiểu về "ma thuật".

Ví dụ:

// frob.h 
#ifndef FROB_H 
#define FROB_H 

#include <shared_ptr> 

class Foo; 
void grind (std::shared_ptr<Foo>); 

#endif 

Lưu ý rằng cách kinh điển để vượt qua shared_ptr là bởi giá trị (ví dụ: loại bỏ các const&).

+0

Tuyên bố chuyển tiếp là không đủ. Kể từ khi gán theo giá trị có thể xóa đối tượng bên dưới bạn cần phải có định nghĩa đầy đủ. (Đây là lý do tại sao tôi sử dụng const & để tránh vấn đề này, nhưng nó không phải lúc nào cũng hoạt động). –

+2

@ edA-qamort-ora-y Điều đó không đúng. Nhiệm vụ sử dụng một deleter tùy chỉnh được cố định bởi các nhà xây dựng. Khai báo chuyển tiếp là đủ cho việc sử dụng 'shared_ptr'; bạn chỉ cần định nghĩa khi gọi hàm tạo của nó. –

+1

dưới mui xe 'shared_ptr' sử dụng kết hợp đa hình thời gian chạy và compiletime, đó là lý do tại sao bạn không cần định nghĩa đầy đủ kiểu được lưu trữ, miễn là bạn không sử dụng' shared_ptr :: operator-> 'và unary 'shared_ptr :: operator *'. Hãy thử nó :) –

3

Có, con trỏ được chia sẻ được thiết kế đặc biệt để hoạt động với các loại không hoàn chỉnh (tính năng sát thủ IMO). Họ chỉ yêu cầu một tuyên bố chuyển tiếp của một lớp, không phải là định nghĩa lớp. Từ số Boost documentation:

Lưu ý rằng scoped_ptr yêu cầu T là loại hoàn chỉnh vào thời gian hủy, nhưng shared_ptr thì không.

Bạn có thể tìm thấy cuộc thảo luận về cách thức hoạt động của here.

Vì con trỏ được chia sẻ nên hoạt động với các loại không đầy đủ, bạn có thể cho chúng tôi một ví dụ cụ thể (tối thiểu) trong đó điều này không phù hợp với bạn?

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