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,但这意味着要学会发现这些问题。