Mặc dù điều này không chính xác nhưng không phải là ý tưởng hay.
MyClass& doSomething() {
return *(new MyClass());
}
Sau khi bạn quay lại, không ai có con trỏ ban đầu, vì vậy sẽ không có ai delete
nó. * Vì vậy, đó là rò rỉ bộ nhớ.
Bạn nên viết khá nhiều khi không viết new
trừ khi bạn có một hàm tạo con trỏ thông minh tương ứng delete
tương ứng.
Trong khi đó, dòng này trong mã ban đầu của bạn:
MyClass a = doSomething();
... sẽ tạo một bản sao của giá trị anyway. Giả sử đó không phải là lỗi khác mà phải được sửa, tại sao lại bận tâm phân bổ một đối tượng và trả về một tham chiếu đến sao chép và rò rỉ? Chỉ trả lại đối tượng theo giá trị:
MyClass doSomething() {
return MyClass();
}
Bây giờ bạn không phải lo lắng về việc xóa bất kỳ thứ gì vì bạn chưa bao giờ tạo bất kỳ thứ gì trên heap.
Thực tiễn tốt nhất thường có thể được tóm tắt trong bốn chữ RAII: Chuyển đổi tài nguyên là khởi tạo. (Và hệ quả, sự hủy diệt đó được giải phóng.) Nếu bạn có thứ gì đó không thể, hoặc đắt tiền, để vượt qua giá trị, thì hãy vượt qua một số xử lý với nó theo giá trị. Ví dụ:
unique_ptr<MyClass> doSomething() {
return unique_ptr<MyClass>(new myClass());
}
unique_ptr<MyClass> a = doSomething();
Bây giờ nó chỉ là con trỏ được sao chép. Bản thân đối tượng được tạo bên trong doSomething
và bị xóa bất cứ khi nào a
vượt quá phạm vi (hoặc, nếu bạn chuyển nó sang biến khác, bất cứ khi nào rằng nằm ngoài phạm vi, v.v.).
Mặt khác, nếu MyClass
chỉ là một số ít giá trị có thể sao chép dễ dàng **, chỉ cần sao chép nó.
* Không phải không thể để xóa nó; bạn luôn có thể đưa con trỏ đến tham chiếu và delete
. Nó chỉ là rất không chắc bạn sẽ bao giờ làm như vậy, và nó sẽ trông lúng túng. Nếu bạn muốn truyền con trỏ xung quanh, hãy chuyển các con trỏ xung quanh. Nếu bạn không muốn bỏ qua các con trỏ xung quanh, hãy quấn quyền sở hữu trong một lớp và chuyển lớp học theo giá trị.
** Bằng "dễ dàng sao chép", tôi có nghĩa là dễ dàng sao chép chúng an toàn và bạn thực sự làm như vậy. Ví dụ, một con trỏ thô hoặc một xử lý tập tin chỉ là một vài byte, và constructor sao chép mặc định sẽ sẵn sàng sao chép chúng cho bạn ... nhưng sau đó bạn kết thúc với nhiều tham chiếu đến cùng một đối tượng heap hoặc tệp, và nó không thể theo dõi người chịu trách nhiệm xóa hoặc đóng nó.
Không cần thiết, tùy chọn đầu tiên là tốt. Ngoài ra, bạn cũng có thể trả lại con trỏ nếu muốn. Tùy thuộc vào bạn. –
Nhưng tham chiếu không được người gọi phân bổ. Nó đã được instantiated trong cuộc gọi .. sau đó tôi figured nếu bạn không sử dụng mới sau đó nó sẽ đi ra khỏi phạm vi bởi vì nó sẽ được trên ngăn xếp chứ không phải là đống. –
@BrianCain Ông hoàn toàn cần 'mới', bởi vì nếu không thì đối tượng sẽ bị hủy ngay khi' doSomething() 'kết thúc. –