C++ 删除传递给C+;中成员函数的新对象+;
我只是想弄清楚我是如何分配作为参数传递的新对象的内存的 假设我有一个定义如下的链接类:C++ 删除传递给C+;中成员函数的新对象+;,c++,C++,我只是想弄清楚我是如何分配作为参数传递的新对象的内存的 假设我有一个定义如下的链接类: class Link{ public: Link(const std::string& value, Link* previous = nullptr, Link* successor = nullptr) : _value{ value }, _previous{ previous }, _successor{ successor }{} Link* Insert(Link* ne
class Link{
public:
Link(const std::string& value, Link* previous = nullptr, Link* successor = nullptr) : _value{ value }, _previous{ previous }, _successor{ successor }{}
Link* Insert(Link* new_link);
Link* getPreviousLink() const{ return _previous; }
Link* getSuccessorLink() const{ return _successor; }
std::string _value;
private:
Link* _previous;
Link* _successor;
};
然后我定义了Link*Insert(Link*),如下所示:
Link* Link::Insert(Link* new_link){
if(!new_link){ return this; }
if(!this){ return new_link; }
new_link->_successor = this;
if(_previous){ _previous->_successor = new_link; }
new_link->_previous = _previous;
_previous = new_link;
return new_link;
}
然后在main()中,我执行以下操作:
int main(){
Link* Cars = new Link("Ford");
Cars = Cars->Insert(new Link("Ferrari"));
Cars = Cars->Insert(new Link("Hummer"));
Cars = Cars->Insert(new Link("Volvo"));
}
我创建了一个名为“Cars”的链接指针,并在堆上分配了一个值为“Ford”的新链接。然后,我将Cars指针指定给从Insert()返回的新链接。再重复此步骤2次
我的问题是,当我将新链接对象作为参数传递时,如何删除或释放分配的内存?我是在Link的析构函数中这样做的吗?如果我只是删除我的Cars指针,它将不会取消分配其他链接。使用智能指针,所有权将明确:
class Link : public std::enable_shared_from_this<Link> {
public:
Link(const std::string& value) : _value{ value } {}
std::shared_ptr<Link> Insert(std::shared_ptr<Link> new_link);
std::shared_ptr<Link> getPreviousLink() const{ return _previous.lock(); }
std::shared_ptr<Link> getSuccessorLink() const{ return _successor; }
std::string _value;
private:
std::weak_ptr<Link> _previous;
std::shared_ptr<Link> _successor;
};
std::shared_ptr<Link> Link::Insert(std::shared_ptr<Link> new_link)
{
if (!new_link){ return shared_from_this(); }
new_link->_successor = shared_from_this();
auto prev = _previous.lock();
if (prev) { prev->_successor = new_link; }
new_link->_previous = prev;
_previous = new_link;
return new_link;
}
int main(){
auto Cars = std::make_shared<Link>("Ford");
Cars = Cars->Insert(std::make_shared<Link>("Ferrari"));
Cars = Cars->Insert(std::make_shared<Link>("Hummer"));
Cars = Cars->Insert(std::make_shared<Link>("Volvo"));
}
class链接:public std::从\u中启用\u共享\u{
公众:
链接(const std::string&value):_value{value}{}
std::shared_ptr Insert(std::shared_ptr new_link);
std::shared_ptr getPreviousLink()常量{return _previous.lock();}
std::shared_ptr getSuccessorLink()常量{return}
std::字符串_值;
私人:
std::弱ptr(前一个);
std::共享的ptr继承者;
};
std::共享链接::插入(std::共享链接新链接)
{
如果(!new_link){return shared_from_this();}
新建链接->\u succession=shared\u from\u this();
auto prev=_previous.lock();
如果(prev){prev->_后继=新链接;}
新建链接->上一个链接=上一个链接;
_先前=新链接;
返回新链接;
}
int main(){
汽车=标准::使共享(“福特”);
汽车=汽车->插入(标准::使共享(“法拉利”);
汽车=汽车->插入(标准::使共享(“悍马”);
汽车=汽车->插入(标准::使共享(“沃尔沃”);
}
使用智能指针,所有权将变得清晰:
class Link : public std::enable_shared_from_this<Link> {
public:
Link(const std::string& value) : _value{ value } {}
std::shared_ptr<Link> Insert(std::shared_ptr<Link> new_link);
std::shared_ptr<Link> getPreviousLink() const{ return _previous.lock(); }
std::shared_ptr<Link> getSuccessorLink() const{ return _successor; }
std::string _value;
private:
std::weak_ptr<Link> _previous;
std::shared_ptr<Link> _successor;
};
std::shared_ptr<Link> Link::Insert(std::shared_ptr<Link> new_link)
{
if (!new_link){ return shared_from_this(); }
new_link->_successor = shared_from_this();
auto prev = _previous.lock();
if (prev) { prev->_successor = new_link; }
new_link->_previous = prev;
_previous = new_link;
return new_link;
}
int main(){
auto Cars = std::make_shared<Link>("Ford");
Cars = Cars->Insert(std::make_shared<Link>("Ferrari"));
Cars = Cars->Insert(std::make_shared<Link>("Hummer"));
Cars = Cars->Insert(std::make_shared<Link>("Volvo"));
}
class链接:public std::从\u中启用\u共享\u{
公众:
链接(const std::string&value):_value{value}{}
std::shared_ptr Insert(std::shared_ptr new_link);
std::shared_ptr getPreviousLink()常量{return _previous.lock();}
std::shared_ptr getSuccessorLink()常量{return}
std::字符串_值;
私人:
std::弱ptr(前一个);
std::共享的ptr继承者;
};
std::共享链接::插入(std::共享链接新链接)
{
如果(!new_link){return shared_from_this();}
新建链接->\u succession=shared\u from\u this();
auto prev=_previous.lock();
如果(prev){prev->_后继=新链接;}
新建链接->上一个链接=上一个链接;
_先前=新链接;
返回新链接;
}
int main(){
汽车=标准::使共享(“福特”);
汽车=汽车->插入(标准::使共享(“法拉利”);
汽车=汽车->插入(标准::使共享(“悍马”);
汽车=汽车->插入(标准::使共享(“沃尔沃”);
}
如果(!this){return new_link;}
表示您在空指针上调用了一个方法。这不是个好主意。不确定这是否是完全未定义的行为,但它的发生通常是代码中需要重新思考的某种迹象。如果(!this){return new_link;}
是可疑的,因为当this
为nul时调用成员函数是不正确的。如果要使用new
,您必须确定哪段代码负责删除该数据结构。是的,您可以在~Link()
中执行此操作,但是您必须确保,在具有静态链接作为后继链接的链接上,您永远不会调用析构函数。@user4581301请参见仔细考虑。A->B,您尝试删除A,A的数据或尝试删除B,B的数据或尝试删除A,A的(第二个)数据或尝试删除B;原则上,这种情况会一直持续下去,实际上,再过几轮之后,调用堆栈就会过载并崩溃。我完全赞成通过实现双链接列表来学习pointercraft,但这意味着要学习发现这些问题。if(!this){return new_link;}
意味着对空指针调用了一个方法。这不是个好主意。不确定这是否是完全未定义的行为,但它的发生通常是代码中需要重新思考的某种迹象。如果(!this){return new_link;}
是可疑的,因为当this
为nul时调用成员函数是不正确的。如果要使用new
,您必须确定哪段代码负责删除该数据结构。是的,您可以在~Link()
中执行此操作,但是您必须确保,在具有静态链接作为后继链接的链接上,您永远不会调用析构函数。@user4581301请参见仔细考虑。A->B,您尝试删除A,A的数据或尝试删除B,B的数据或尝试删除A,A的(第二个)数据或尝试删除B;原则上,这种情况会一直持续下去,实际上,再过几轮之后,调用堆栈就会过载并崩溃。我完全赞成实现一个双链接列表,以便学习pointercraft,但这意味着要学会发现这些问题。