Tôi muốn biết tôi có cần viết hàm hủy trong lớp khi không sử dụng con trỏ thô nữa không? Chỉ cần tăng con trỏ thông minh.Con trỏ & phá hủy thông minh
Trả lời
Bạn nên luôn cân nhắc việc cung cấp trình phá hủy. Bạn sẽ sử dụng nó để giải phóng bất kỳ tài nguyên nào mà lớp của bạn đang nắm giữ. Thường thì các lớp hủy lớp smart_ptr của tôi trống rỗng nhưng không phải lúc nào cũng vậy. Các luồng tệp, kết nối cơ sở dữ liệu, v.v. tất cả đều cần dọn dẹp thích hợp.
Tất cả những thứ đó có thể được làm sạch bằng cách gói chúng trong một lớp RAII, giống như một 'smart_ptr'. Với C++ 11, class destructors sẽ rất hiếm. –
@Mooing Không đùa đâu. Con trỏ thông minh/RAII giảm mã của tôi rất nhiều và các trình phá hoại của tôi thường trống. Họ mất một thời gian để làm quen, nhưng họ đáng được học hỏi chắc chắn. – Aura
Tăng con trỏ thông minh bằng chính mình không có liên quan gì đến nhu cầu phá hủy. Tất cả những gì họ làm là loại bỏ sự cần thiết cho bạn để gọi xóa trên bộ nhớ được cấp phát mà họ đang quản lý hiệu quả. Do đó, nếu trước đó bạn bắt đầu sử dụng con trỏ thông minh, tất cả những gì bạn có trong trình phá hủy là gọi để xóa và xóa [] giải phóng bộ nhớ của các thành viên lớp được phân bổ động và bây giờ bạn đã chuyển tất cả các con trỏ thông thường sang con trỏ thông minh, bạn có thể có lẽ chỉ cần chuyển sang một destructor trống như bây giờ họ sẽ làm sạch cho mình khi họ đi ra khỏi phạm vi.
Tuy nhiên, nếu vì lý do gì, bạn có một lớp học cần dọn dẹp (dọn dẹp tệp, ổ cắm, tài nguyên khác, v.v.), bạn vẫn sẽ cần phải cung cấp một destructor để làm điều đó.
Hãy cho tôi biết nếu điều đó có ích.
Tất cả những thứ đó có thể được làm sạch bằng cách gói chúng trong một lớp RAII, giống như một 'smart_ptr'. Với C++ 11, class destructors sẽ rất hiếm. –
Mỗi loại tài nguyên phải có một lớp RAII để quản lý tài nguyên đó. Nếu bạn cũng có một con trỏ thông minh với ngữ nghĩa bản sao sâu (khá dễ làm), đó là tất cả những gì bạn cần để quản lý tài nguyên của bạn 99,9% thời gian. Tôi không biết tại sao unique_ptr
không làm bản sao sâu, cũng như không có con trỏ thông minh nào, nhưng nếu bạn có hai thứ đó, bạn không cần viết các hàm tạo bản sao, di chuyển các hàm tạo, toán tử gán, di chuyển các toán tử gán cũng như các hàm hủy. Bạn có thể hoặc có thể không phải cung cấp các nhà xây dựng khác (bao gồm cả nhà xây dựng mặc định), nhưng đó là năm nơi ít hơn để phạm sai lầm.
#include <memory>
template<class Type, class Del = std::default_delete<Type> >
class deep_ptr : public std::unique_ptr<Type, Del> {
public:
typedef std::unique_ptr<Type, Del> base;
typedef typename base::element_type element_type;
typedef typename base::deleter_type deleter_type;
typedef typename base::pointer pointer;
deep_ptr() : base() {}
//deep_ptr(std::nullptr_t p) : base(p) {} //GCC no has nullptr_t?
explicit deep_ptr(pointer p) : base() {}
deep_ptr(pointer p, const typename std::remove_reference<Del>::type &d) : base(p, d) {} //I faked this, it isn't quite right
deep_ptr(pointer p, typename std::remove_reference<Del>::type&& d): base(p, d) {}
deep_ptr(const deep_ptr& rhs) : base(new Type(*rhs)) {}
template<class Type2, class Del2>
deep_ptr(const deep_ptr<Type2, Del2>& rhs) : base(new Type(*rhs)) {}
deep_ptr(deep_ptr&& rhs) : base(std::move(rhs)) {}
template<class Type2, class Del2>
deep_ptr(deep_ptr<Type2, Del2>&& rhs) : base(std::move(rhs)) {}
deep_ptr& operator=(const deep_ptr& rhs) {base::reset(new Type(*rhs)); return *this;}
template<class Type2, class Del2>
deep_ptr& operator=(const deep_ptr<Type2, Del2>& rhs) {base::reset(new Type(*rhs)); return *this;}
deep_ptr& operator=(deep_ptr&& rhs) {base::reset(rhs.release()); return *this;}
template<class Type2, class Del2>
deep_ptr& operator=(deep_ptr<Type2, Del2>&& rhs) {base::reset(rhs.release()); return *this;}
void swap(deep_ptr& rhs) {base::swap(rhs.ptr);}
friend void swap(deep_ptr& lhs, deep_ptr& rhs) {lhs.swap(rhs.ptr);}
};
Với lớp này (hoặc tương tự), bạn không cần gì nhiều!
struct dog {
deep_ptr<std::string> name;
};
int main() {
dog first; //default construct a dog
first.name.reset(new std::string("Fred"));
dog second(first); //copy construct a dog
std::cout << *first.name << ' ' << *second.name << '\n';
second.name->at(3) = 'o';
std::cout << *first.name << ' ' << *second.name << '\n';
second = first; //assign a dog
std::cout << *first.name << ' ' << *second.name << '\n';
}
Như đã trình bày ở http://ideone.com/Kdhj8
- 1. OpenCV hoặc Boost con trỏ thông minh
- 2. Con trỏ thông minh trong Qt
- 3. C++ Hiệu suất con trỏ thông minh
- 4. Con trỏ thông minh và tham khảo
- 5. Con trỏ thông minh và đếm số liệu trong Java
- 6. Sự khác biệt giữa các con trỏ thông minh Boost và con trỏ thông minh tiêu chuẩn là gì?
- 7. Quy tắc ba với con trỏ thông minh?
- 8. pimpl-idiom trong mẫu; con trỏ thông minh nào?
- 9. Khi nào tôi nên sử dụng con trỏ thô trên con trỏ thông minh?
- 10. sử dụng mem_fun() cho vùng chứa con trỏ thông minh
- 11. khởi động đúng cách thông minh con trỏ mảng
- 12. thúc đẩy con trỏ thông minh và BOOST_NO_MEMBER_TEMPLATES
- 13. C++ 11 con trỏ thông minh và đa hình
- 14. Con trỏ thông minh và xử lý ngoại lệ
- 15. thành ngữ hàm tạo ảo với con trỏ thông minh
- 16. Tại sao bạn không nên sử dụng tham chiếu đến con trỏ thông minh?
- 17. Các con trỏ thông minh có phá vỡ nguyên tắc giảm thiểu #includes trong các tệp tiêu đề không?
- 18. Làm cách nào để hủy lớp an toàn bằng con trỏ thông minh thành loại đối tượng không đầy đủ?
- 19. Tôi có thể viết một hàm C++ chấp nhận cả một con trỏ thô và một con trỏ thông minh?
- 20. trả về một 'con trỏ' được yêu cầu phải được giữ bởi một con trỏ thông minh
- 21. Tìm rò rỉ bộ nhớ do con trỏ thông minh gây ra
- 22. Phá hủy WebWorkers
- 23. Làm thế nào để ép buộc chỉ trình con trỏ thông minh cho một lớp học?
- 24. Truyền con trỏ thông minh làm đối số bên trong một lớp: scoped_ptr hoặc shared_ptr?
- 25. Có thể sử dụng một con trỏ thông minh C++ cùng với malloc của C không?
- 26. Con trỏ thông minh/quản lý bộ nhớ an toàn cho C?
- 27. Sử dụng con trỏ thông minh trong cấu trúc hoặc lớp
- 28. Hình phạt gói con trỏ thông minh. Bản ghi nhớ với std :: map
- 29. Cách tốt nhất để triển khai con trỏ thông minh trong C++ là gì?
- 30. LISP - cấu trúc phá hoại và không phá hủy
lẽ @simchona biết một cái gì đó tôi không, nhưng con trỏ thông minh không làm giảm bớt nhu cầu dọn dẹp, họ chỉ cần thay đổi như thế nào (khi nào) nó sẽ xảy ra. –
Tôi đang đọc câu hỏi này, làm tăng các con trỏ thông minh vào và xóa bỏ sự cần thiết phải viết các trình phá hủy trong nhiều trường hợp? Đúng không? – gymbrall
@Yeah, nếu bạn có một deep_pointer (hoặc bất cứ điều gì nó được gọi là), thì bạn không cần gán/di chuyển/destructor/constructors. (Mặc dù các nhà xây dựng đôi khi vẫn có thể tiện dụng) –