Class 智能指针&;析构函数
我想知道,当我不再使用原始指针时,是否需要在类中编写析构函数?只需增加智能指针。 你应该总是考虑提供析构函数。您可以使用它来释放您的类所持有的任何资源。我的smart_ptr类析构函数通常是空的,但并不总是空的。文件流、数据库连接等都需要适当的清理。Boost智能指针本身与析构函数的需要无关。它们所做的只是消除您对它们有效管理的分配内存调用delete的需要。话虽如此,如果在您开始使用智能指针之前,析构函数中所有的调用都是delete和delete[]释放动态分配的类成员的内存,现在您已经将所有常规指针切换到智能指针,您可能只需要切换到一个空的析构函数,因为当它们超出范围时,它们将自己清理 但是,如果出于任何原因,您有一个类需要进行清理(文件清理、套接字、其他资源等),那么您仍然需要提供析构函数来进行清理Class 智能指针&;析构函数,class,boost,destructor,smart-pointers,Class,Boost,Destructor,Smart Pointers,我想知道,当我不再使用原始指针时,是否需要在类中编写析构函数?只需增加智能指针。 你应该总是考虑提供析构函数。您可以使用它来释放您的类所持有的任何资源。我的smart_ptr类析构函数通常是空的,但并不总是空的。文件流、数据库连接等都需要适当的清理。Boost智能指针本身与析构函数的需要无关。它们所做的只是消除您对它们有效管理的分配内存调用delete的需要。话虽如此,如果在您开始使用智能指针之前,析构函数中所有的调用都是delete和delete[]释放动态分配的类成员的内存,现在您已经将所有
如果有帮助,请告诉我。每种资源类型都应该有一个RAII类来管理该资源。如果您还有一个具有深度复制语义的智能指针(非常容易做到),那么您就可以在99.9%的时间内管理资源。我不知道为什么
unique\u ptr
不做深度复制,也不做任何boost智能指针,但是如果你有这两个东西,你就不需要写复制构造函数、移动构造函数、赋值操作符、移动赋值操作符,也不需要析构函数。您可能需要也可能不需要提供其他构造函数(包括默认构造函数),但这减少了五个出错的地方
#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);}
};
#包括
模板
类deep\u ptr:public std::unique\u ptr{
公众:
typedef std::唯一的ptr基;
typedef typename base::element_type element_type;
typedef typename base::deleter_type deleter_type;
typedef typename base::指针;
deep_ptr():base(){}
//deep_ptr(std::nullptr_t p):base(p){}//GCC没有nullptr_t?
显式deep_ptr(指针p):base(){}
deep_ptr(指针p,const typename std::remove_reference::type&d):base(p,d){}//我伪造了这个,它不太正确
deep_ptr(指针p,typename std::remove_reference::type&&d):基(p,d){
deep_ptr(const deep_ptr&rhs):基(新类型(*rhs)){
模板
deep_ptr(const deep_ptr&rhs):基(新类型(*rhs)){
deep_ptr(deep_ptr&&rhs):基(std::move(rhs)){}
模板
deep_ptr(deep_ptr&&rhs):基(std::move(rhs)){}
deep_ptr&operator=(const deep_ptr&rhs){base::reset(新类型(*rhs));返回*this;}
模板
deep_ptr&operator=(const deep_ptr&rhs){base::reset(新类型(*rhs));返回*this;}
deep_ptr&operator=(deep_ptr&rhs){base::reset(rhs.release());返回*this;}
模板
deep_ptr&operator=(deep_ptr&rhs){base::reset(rhs.release());返回*this;}
无效交换(deep_ptr&rhs){base::swap(rhs.ptr);}
好友无效交换(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';
}
结构狗{
深部ptr名称;
};
int main(){
dog first;//默认构造一个dog
first.name.reset(新的std::string(“Fred”);
第二只狗(第一只);//复制构造一只狗
std::cout也许@simchona知道一些我不知道的事情,但是智能指针并不能减轻清理的需要,它们只是改变了清理的方式(何时)。我在阅读这个问题时认为,在几乎所有情况下,增强智能指针本身就可以消除编写析构函数的需要吗?对吗?是的,如果你有一个深层指针的话(或者不管它叫什么),那么你就不需要赋值/移动/析构函数/构造函数了所有这些东西都可以通过将它们包装到RAII类中来清理,比如
智能\u ptr
。使用C++11,类析构函数应该很少见。@Mooing不是开玩笑。智能指针/RAII将我的代码减少了很多,而我的析构函数通常是空的。它们需要一段时间来适应,但它们确实值得学习。所有这些东西都可以被清除通过将它们包装在一个RAII类中,比如smart_ptr
。对于C++11,类析构函数应该很少见。@Mooningduck你是建议使用空析构函数,还是完全删除它们?最好使用一个非用户定义的析构函数,对吗?@MaxBarraclough:对。析构函数是一个绝对令人惊奇的概念,它们是如此神奇,以至于开发人员实际上不必编写一个。他们应该始终使用默认的析构函数。请参阅