2010-08-23 49 views
34

Tôi không chắc chắn về một cách tốt để khởi tạo một shared_ptr đó là một thành viên của một lớp học. Bạn có thể cho tôi biết, liệu cách tôi chọn trong C::foo() có ổn không, hoặc có giải pháp tốt hơn không?Cách khởi tạo shared_ptr là thành viên của lớp học?

class A 
{ 
    public: 
    A(); 
}; 

class B 
{ 
    public: 
    B(A* pa); 
}; 

class C 
{ 
    boost::shared_ptr<A> mA; 
    boost::shared_ptr<B> mB; 
    void foo(); 
}; 

void C::foo() 
{ 
    A* pa = new A; 
    mA = boost::shared_ptr<A>(pa); 
    B* pB = new B(pa); 
    mB = boost::shared_ptr<B>(pb); 
} 
+2

Sử dụng danh sách khởi tạo. – Chubsdad

+0

chubsdad: Sẽ không hoạt động trong các thành viên, chỉ trong ctors. – MSalters

+0

@MSalters: Tôi không biết bạn đang cố nói gì. – sbi

Trả lời

30

Mã của bạn là khá chính xác (nó hoạt động), nhưng bạn có thể sử dụng danh sách khởi tạo, như thế này:

C::C() : 
    mA(new A), 
    mB(new B(mA.get()) 
{ 
} 

Mà thậm chí còn chính xác và an toàn.

Nếu vì bất kỳ lý do gì, new A hoặc new B ném, bạn sẽ không bị rò rỉ.

Nếu new A ném, thì không có bộ nhớ nào được cấp phát và ngoại lệ cũng hủy bỏ hàm tạo của bạn. Không có gì được xây dựng.

Nếu new B ném và ngoại lệ sẽ vẫn hủy bỏ hàm tạo của bạn: mA sẽ bị hủy đúng cách.

Tất nhiên, vì phiên bản B yêu cầu một con trỏ đến một phiên bản A, thứ tự khai báo của các thành viên vấn đề.

Trình tự khai thành viên là chính xác trong ví dụ của bạn, nhưng nếu nó được đảo ngược, sau đó trình biên dịch của bạn có lẽ sẽ phàn nàn về mB beeing khởi tạo trước mA và instantiation của mB có khả năng sẽ thất bại (vì mA sẽ không được xây dựng nào, do đó gọi mA.get() gọi hành vi không xác định).


Tôi cũng xin đề nghị bạn nên sử dụng một shared_ptr<A> thay vì một A* như một tham số cho B constructor của bạn (nếu nó làm cho giác quan và nếu bạn có thể chấp nhận chi phí ít). Nó có lẽ sẽ an toàn hơn.

Có thể đảm bảo rằng một phiên bản B không thể tồn tại mà không có trường hợp A và lời khuyên của tôi không áp dụng, nhưng chúng tôi thiếu ngữ cảnh ở đây để đưa ra lời khuyên dứt khoát về vấn đề này.

+1

Cho rằng bạn đang dựa vào nó, nó có giá trị nói về việc làm thế nào thứ tự xây dựng của các thành viên hoạt động và các điểm chuỗi liên quan. –

+0

@ereOn - Loại trả về cho hàm tạo? – DumbCoder

+0

@DumbCoder: Được sao chép từ câu hỏi mà nó cũng sai. Tôi sửa nó rồi. – sbi

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