Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 智能指针&;析构函数_Class_Boost_Destructor_Smart Pointers - Fatal编程技术网

Class 智能指针&;析构函数

Class 智能指针&;析构函数,class,boost,destructor,smart-pointers,Class,Boost,Destructor,Smart Pointers,我想知道,当我不再使用原始指针时,是否需要在类中编写析构函数?只需增加智能指针。 你应该总是考虑提供析构函数。您可以使用它来释放您的类所持有的任何资源。我的smart_ptr类析构函数通常是空的,但并不总是空的。文件流、数据库连接等都需要适当的清理。Boost智能指针本身与析构函数的需要无关。它们所做的只是消除您对它们有效管理的分配内存调用delete的需要。话虽如此,如果在您开始使用智能指针之前,析构函数中所有的调用都是delete和delete[]释放动态分配的类成员的内存,现在您已经将所有

我想知道,当我不再使用原始指针时,是否需要在类中编写析构函数?只需增加智能指针。

你应该总是考虑提供析构函数。您可以使用它来释放您的类所持有的任何资源。我的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:对。析构函数是一个绝对令人惊奇的概念,它们是如此神奇,以至于开发人员实际上不必编写一个。他们应该始终使用默认的析构函数。请参阅