Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从弱\u从\u获取的弱\u ptr此()无效_C++_Smart Pointers_Weak Ptr - Fatal编程技术网

C++ 从弱\u从\u获取的弱\u ptr此()无效

C++ 从弱\u从\u获取的弱\u ptr此()无效,c++,smart-pointers,weak-ptr,C++,Smart Pointers,Weak Ptr,下面是一个简单的例子: 源代码: #include <memory> #include <iostream> class A : public std::enable_shared_from_this<A> { public: A(std::weak_ptr<A> up) : up_(up) { std::cout << "A" << " has up_? " << ((up_

下面是一个简单的例子:

源代码:

#include <memory>
#include <iostream>

class A : public std::enable_shared_from_this<A>
{
 public:
  A(std::weak_ptr<A> up) : up_(up)
  {
    std::cout << "A" << " has up_? " <<
        ((up_.lock()) ? "yes" : "no")
              << std::endl;
  }

  void grow()
  {
    if (dp_)
      dp_->grow();
    else
      dp_ = std::make_shared<A>(weak_from_this());
  }

 private:
  std::weak_ptr<A> up_;
  std::shared_ptr<A> dp_;
};

int main()
{
  auto wp = std::weak_ptr<A>();
  A a(wp);
  for (int i = 0; i < 3; ++i)
  {
    a.grow();
  }
  return 0;
}
期望的行为:

clang++ minimal.cpp && ./a.out
A has up_? no
A has up_? yes
A has up_? yes
A has up_? yes
事实上,我想知道为什么原始输出中的第二行显示“否”?我认为,当我们第一次创建类型A的对象时(正好在其构造完成之后,在我们对其调用
grow()
之前),我们有一个有效的对象,我们可以将引用传递到任何我们想传递到的地方,不是吗?

来自cppreference,关于

返回一个
std::weak_ptr
,它跟踪引用
*此
的所有现有
std::shared_ptr
*此
的所有权

同时

A a(wp);

这不是任何
共享\u ptr
跟踪的对象。它是一个具有自动存储持续时间的普通对象。如果你想从这个
弱\u工作,必须有一个
共享\u ptr
跟踪第一个对象。

从这个
继承
std::enable\u shared\u是一个承诺,即每个
a
都属于
std::shared\u ptr
。你打破了它promise@Calethsource?@Fureeish“仅允许在以前共享的对象上,即在由
std::shared\u ptr
管理的对象上,从\u this
调用
shared\u。否则,行为未定义”。C++不执行LISKOV替代原则,但它是一个非常有用的准则。@ Calthi我相信当你结合<代码> C++ >代码>和“你违背了诺言”这样的短语时,你必须在技术上正确(根据标准的规则),否则你根本就不正确。我明白你想说的,但原则上,拥有一个
A
对象,它不受任何
std::shared_ptr
的管理,只要你不调用需要它作为前提条件的方法,就没有什么错。
A a(wp);