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.
Sử dụng danh sách khởi tạo. – Chubsdad
chubsdad: Sẽ không hoạt động trong các thành viên, chỉ trong ctors. – MSalters
@MSalters: Tôi không biết bạn đang cố nói gì. – sbi