0
#include <memory>

struct B;    

struct A
{
     std::shared_ptr<B> field1_;
     A():field1_ (std::make_shared<B>()){}
};

template<class A>
struct B: std::enable_shared_from_this<B<A>>
{
     A *field1_; 

     void stop()
     {
        delete field1_; //~= delete this
     }

     A* start()
     {
         field1_ = new A(shared_from_this());
         return field1_;
     }
};

int main()
{
    A * reftoA = nullptr;

    {
        std::shared_ptr<B<A>> b = std::make_shared<B<A>>();
        reftoA = b->start();
    }

    reftoAa->field1_->stop();
}

我在生产中有一个错误,我想知道上面的代码是否会破坏 HEAP 或导致未定义的行为。

编辑:我已将上面的代码更改为更接近我的真实代码。

4

3 回答 3

2

该代码甚至不应该编译,因为

void setA(A* a):field1_(a){}

这是无效的。

另外,既然您已经在使用智能指针,为什么还要继续A *field1_;使用B

于 2012-11-05T09:54:33.917 回答
2

从它自己的方法中删除一个对象是一种非常常见的技术,如果这样做是故意和小心的。许多较旧的引用计数设计都以这种方式工作,例如 COM 和 Mozilla 代码库等衍生产品。请参阅: http: //www.parashift.com/c++-faq-lite/delete-this.html获取建议。

但在这种情况下,它看起来像是一种意外混叠。StructB似乎部分地像 中的对象的“所有者” field1_,因此赋予它删除它的权利,然后你对它玩了一个邪恶的把戏。

这是 C++,实际上不可能在不查看完整程序的源代码的情况下判断这是否会导致未定义的行为。

于 2012-11-05T10:01:10.823 回答
0

像这样的生产代码应该被判处死刑。

你调用B::funcwhich 会破坏A它持有指向的指针,然后在你再次main删除A。你期待什么?

于 2012-11-05T10:30:01.497 回答