2016-01-13 55 views
0

我传递的unique_ptr的功能,然后将指针移动到另一个的unique_ptr,一切工作正常的需要,但同时点是当它熄灭的unique_ptr不调用析构函数的范围。的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(); 
    } 
} 
+0

对象必须被销毁,使用'delete'释放。 – Pixelchemist

+0

但新被分配到unique_ptr,所以它的unique_ptr的作业被删除了。 – DJB

+5

的'unique_ptr'问题是其成员'* obj1',当后者被破坏就会受到破坏 - 但'* obj1'永远不会销毁:你的程序泄露了。 –

回答

0

你的变量通过obj1指出不delete d,因此它的成员将不会被破坏,直到delete发生和unique_ptr将仍然活着,那么析构函数永远不会被调用。

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

+0

虽然你对错误是正确的(并且我喜欢使用unique_ptr作为分配对象的建议),但你的措辞有点模糊:“你的变量obj1未被删除”严格地说是错误的。当main()返回时,'obj1'被正确删除,这正是为什么使用本地unique_ptr会起作用的原因。它是* obj1指向*​​的*对象,即Igor将它放在注释中,'* obj1'不会被'delete'd。 –

+0

@ PeterA.Schneider是的你是对的,我会纠正这个逃亡 – dkg

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. 
} 

在程序结束时,操作系统回收程序使用的内存,但并不意味着它调用的obj1析构函数。

如果析构函数负责释放内存以外的资源,例如网络连接,共享文件/文件夹上的锁定等,当程序结束而没有析构函数被调用时,它们将不会被释放。用`new`分配