我想知道当我不再使用原始指针时,是否需要在类中编写析构函数?只需提升智能指针。
答案 0 :(得分:11)
提升智能指针本身与析构函数的需求无关。他们所做的就是不再需要在他们有效管理的已分配内存上调用delete。所以说,如果在你开始使用智能指针之前你所有的析构函数都是调用删除和删除[]释放动态分配的类成员的内存,你现在已经将所有那些常规指针切换到智能指针,你可以可能只是切换到一个空的析构函数,因为当它们超出范围时它们现在将自行清理。
但是,如果由于某种原因,你有一个需要进行清理的类(文件清理,套接字,其他资源等),你仍然需要提供一个析构函数来完成它。
如果有帮助,请告诉我。
答案 1 :(得分:4)
每种资源类型都应该有一个RAII类来管理该资源。如果你还有一个带有深拷贝语义的智能指针(很容易做到),那么99.9%的时间都需要管理你的资源。我不知道为什么unique_ptr
没有做深拷贝,也没有任何提升智能指针,但如果你有这两件事,你不需要编写复制构造函数,移动构造函数,赋值运算符,移动赋值运算符,也不是破坏者。您可能需要或可能不需要提供其他构造函数(包括默认构造函数),但这样可以减少五个错误。
#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);}
};
使用这个类(或类似的类),你根本不需要太多!
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';
}
所示
答案 2 :(得分:-2)
您应该始终考虑提供析构函数。您可以使用它来释放您的班级所持有的任何资源。通常我的smart_ptr类析构函数是空的但并非总是如此。文件流,数据库连接等都需要适当的清理。