C++ 对象X的弱ptr在对象X'期间是否仍然有效;毁灭

C++ 对象X的弱ptr在对象X'期间是否仍然有效;毁灭,c++,language-lawyer,C++,Language Lawyer,我有一些类似于以下内容: class A { std::weak_ptr<B> r; A (std::weak_ptr<B> x) : r(x) {} ~A() { r.lock(); } }; class B : std::enable_shared_from_this<B> { std::shared_ptr<A> r; foo() { r = std::make_shared<A>(s

我有一些类似于以下内容:

class A {
  std::weak_ptr<B> r;
  A (std::weak_ptr<B> x) : r(x) {}

  ~A() {
    r.lock();
  }
};


class B : std::enable_shared_from_this<B> {
  std::shared_ptr<A> r;
  foo() {
    r = std::make_shared<A>(shared_from_this());
  }
};
A类{
std::弱ptr;
A(std::弱_ptrx):r(x){}
~A(){
r、 锁();
}
};
B类:std::从该{
std::共享的ptr;
foo(){
r=std::使_共享(从_this()共享_);
}
};
在破坏B的过程中,调用~A();但它想调用被破坏的对象。 忽略与此相关的设计问题,行为是已定义的,还是依赖于编译器?

表达式r.lock()将失败(即返回一个空的共享\u ptr)

弱\u ptr有效,但共享\u ptr已在破坏B

事件的顺序将是:

shared_ptr<B>::~shared_ptr()
 <strong reference count reduced to 0, destruction process begins>
 <shared_ptr<B> is now empty>
  ~B()
   shared_ptr<A>::~shared_ptr()
    ~A()
     weak_ptr<B>::lock -> returns shared_ptr<B>(nullptr)
shared\u ptr::~shared\u ptr()
<强引用计数减少到0,销毁过程开始>
~B()
共享\u ptr::~shared\u ptr()
~A()
弱\u ptr::lock->返回共享\u ptr(nullptr)
这里有一股强烈的次优设计的味道。正式写出需求可能是个好主意。

表达式r.lock()将失败(即返回一个空的共享\u ptr)

弱\u ptr有效,但共享\u ptr已在破坏B

事件的顺序将是:

shared_ptr<B>::~shared_ptr()
 <strong reference count reduced to 0, destruction process begins>
 <shared_ptr<B> is now empty>
  ~B()
   shared_ptr<A>::~shared_ptr()
    ~A()
     weak_ptr<B>::lock -> returns shared_ptr<B>(nullptr)
shared\u ptr::~shared\u ptr()
<强引用计数减少到0,销毁过程开始>
~B()
共享\u ptr::~shared\u ptr()
~A()
弱\u ptr::lock->返回共享\u ptr(nullptr)

这里有一股强烈的次优设计的味道。正式写出需求可能是个好主意。

您能提供一个使用示例吗?一个问题是:一个命名为a的实例得到一个B的实例,B持有一个对同一个a的弱引用?破坏的顺序与构造的顺序相反,因此
B
仍然是“有效的”,但在
r
之后访问成员将是UB。@tobi303对不起-完全正确;问题:updated@Theforgotten正确,B的一个实例包含一个A,该A包含对该B的弱引用。如果是
r
的销毁调用了
B
的析构函数,则
A
的析构函数体已经完成。storagre仍然存在,因此您可以获取指向它的指针,但您不能以任何方式使用它。您能提供一个使用示例吗?一个问题是:一个命名为a的实例得到一个B的实例,B持有一个对同一个a的弱引用?破坏的顺序与构造的顺序相反,因此
B
仍然是“有效的”,但在
r
之后访问成员将是UB。@tobi303对不起-完全正确;问题:updated@Theforgotten正确,B的一个实例包含一个A,该A包含对该B的弱引用。如果是
r
的销毁调用了
B
的析构函数,则
A
的析构函数体已经完成。storagre仍然存在,因此您可以获取指向它的指针,但您不能以任何方式使用它。