unique_ptr不会调用析构函数来释放指针

时间:2016-01-13 06:22:58

标签: c++ c++11

我将unique_ptr传递给函数,然后将指针移动到另一个unique_ptr,所有工作都正常,但是当point is unique_ptr不会调用它超出范围时的析构函数。

以下是我的代码。和它的输出,代码是在eclipse。

enter image description here

#include <iostream>
#include <memory>

using namespace std;

class BaseCcExpander;
class DeriveHandler;
class ExpansionRuleExecuter;
class DeriveType1;

class ParamBase
{
public :

    ParamBase()
    {
        std::cout << "Ctor:ParamBase:\n";
    }
    std::unique_ptr<ExpansionRuleExecuter> paramexpander;
    virtual ~ParamBase()     { std::cout << "Dtor::~ParamBase:\n"; }
    virtual void attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);

};

ParamBase* obj;
void ParamBase::attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander)
{
    std::cout << "In:  ParamBase::attachHandler :\n";
    paramexpander = std::move(xbaseExpander);
}

class ExpansionRuleExecuter
{
public:
    ExpansionRuleExecuter()
    {
        std::cout << "Ctor ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
    }
    virtual ~ExpansionRuleExecuter(){

        std::cout << "Dtor ~ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
    }
    virtual void handleExpansion() = 0;

};
class DeriveHandler : public ExpansionRuleExecuter
{
public:
    DeriveHandler()
    {
        std::cout << "Ctor::DeriveHandler:\n" << endl;
    }

     ~DeriveHandler()
    {
        std::cout << "Dtor::~DeriveHandler:\n" << endl;
    }

     void handleExpansion()
     {
         std::cout << "DeriveHandler expanded\n" << endl;
     }
};



ParamBase *obj1;
class BaseCcExpander
{
public:
    BaseCcExpander()
    {
        std::cout << "Ctor::BaseCcExpander:\n" << endl;
    }

    virtual ~BaseCcExpander()
    {
        std::cout << "Dtor::~BaseCcExpander:\n" << endl;
    }

    typedef unique_ptr<ExpansionRuleExecuter> ccHandler;
    BaseCcExpander::ccHandler ccBaseHandler;

    void attachHandler(int paramGrp, int paramId,std::unique_ptr<ExpansionRuleExecuter> xhandler)
    {
        std::cout << "BaseCcExpander::attachHandler:\n" << endl;
        obj1->attachBase(paramGrp,paramId,std::move(xhandler));
    }

};


class DeriveType1 : public ParamBase
{
public :
    DeriveType1()      { std::cout << "Ctor: DeriveType--------1:\n"  << endl;}
    ~DeriveType1()     { std::cout << "Dtor::~DeriveType---------1\n" << endl;}
    void attachBase(std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};

BaseCcExpander ccexpander;


int main()
{

    obj1 = new(DeriveType1);
    ccexpander.attachHandler(1,2,std::unique_ptr<ExpansionRuleExecuter>(new DeriveHandler));
    if(obj1->paramexpander.get())
    {
        ExpansionRuleExecuter *expand = obj1->paramexpander.get();
        expand->handleExpansion();
    }
}

2 个答案:

答案 0 :(得分:1)

您在评论中写道:

  

但是obj1即使在程序结束后也不会破坏全局空间,它应该销毁。

这里有一些误解。 obj1被销毁,但它所指向的对象在obj1被销毁时不会被删除。如果编译器这样做了,你就无法使用:

int main()
{
   int i = 10;
   int* ip = &i;
   // You don't want the run time to call the equivalent of
   // delete ip;
   // when the function returns. That will lead to undefined behavior
   // since ip does not point to memory allocated from the heap.
}

当程序结束时,OS回收程序使用的内存,但这并不意味着它调用obj1的析构函数。

如果析构函数负责释放除内存之外的资源,例如网络连接,共享文件/文件夹等等,则程序结束时不会释放它们,而不会调用析构函数。

答案 1 :(得分:0)

obj1指向的变量不是delete d,因此在delete发生并且unique_ptr保持活动然后析构函数将保持活动状态之前,其成员不会被销毁永远不会被召唤。

您应该在程序结束时在delete上致电obj1或在其上使用unique_ptr