我将unique_ptr传递给函数,然后将指针移动到另一个unique_ptr,所有工作都正常,但是当point is unique_ptr不会调用它超出范围时的析构函数。
以下是我的代码。和它的输出,代码是在eclipse。
#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 :(得分: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
。