2016-01-13 49 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`分配