Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++ 返回共享的成员变量是否安全_C++_C++11_Shared Ptr - Fatal编程技术网

C++ 返回共享的成员变量是否安全

C++ 返回共享的成员变量是否安全,c++,c++11,shared-ptr,C++,C++11,Shared Ptr,假设我有以下代码,这是我问题的简化示例: #include <string> #include <iostream> #include <memory> class A{ public: std::string name() { return "class A"; } }; class B{ public: B(){ m_a = std::make_shared<A>(); } std::shared_ptr

假设我有以下代码,这是我问题的简化示例:

#include <string>
#include <iostream>
#include <memory>


class A{
  public:
  std::string name() { return "class A"; }
};

class B{
  public:
  B(){
    m_a = std::make_shared<A>();
  }

  std::shared_ptr<A> get_a() { return m_a; }

  private:
  std::shared_ptr<A> m_a;
};

std::shared_ptr<A> foo()
{
  B b;
  return b.get_a();
}

int main()
{
  auto a = foo();
  auto name = a->name();
  std::cout << name;
  return 1;
}
#包括
#包括
#包括
甲级{
公众:
std::string name(){return“class A”;}
};
B类{
公众:
B(){
m_a=std::使_共享();
}
std::shared_ptr get_a(){return m_a;}
私人:
std::共享ptr m_a;
};
std::shared_ptr foo()
{
B B;
返回b.get_a();
}
int main()
{
自动a=foo();
自动名称=a->name();
std::cout那
foo

shared_ptr<A> foo()
{
  B b;
  return b.get_a();
}
将堆实例从销毁状态保存到作用域结束

因此,我认为这是安全的,BS,虽然创建者毕竟是一个用户,可能有许多他们创建和发布的共享资产。

换句话说,最后一个人关灯,而不是开灯的人

这是安全的

shared\u ptr
在堆上创建跟踪变量。这使得对象
B
更加复杂,因为即使在堆栈上创建对象,它也会从堆中分配
a
。可能会影响性能


当跟踪数据的所有用户都停止访问它时,共享的ptr将被删除。

是的,它是安全的。如果这不安全,那么共享的ptr将毫无用处

“b”是b的一个实例,将在函数foo结束时释放

是的,但是它的
std::shared_ptr
在那之前就被复制了

让我们看看函数的最后一行真正做了什么:

get_a()
生成一个
std::shared_ptr
,将其复制到一个临时对象。然后再次复制该临时
std::shared_ptr
对象,使其成为
main
中调用的结果

(由于返回值优化,实际副本甚至可能被省略,但这不会改变任何事情。如果有任何改变,它会使安全性更容易理解。)

只有到那时,
b
才被销毁,但其中的
std::shared_ptr
已被复制

b
中的
std::shared_ptr
实例也被销毁,但是
A
对象的内存没有被释放。这就是
std::shared_ptr的全部要点——它知道它被复制的频率,并且只有在最后一个副本被销毁时才会释放动态分配的内存

主函数中的“a”是B::m_a的共享ptr

不。它是一个
std::shared_ptr
,但就是这样。它与原始
B::m_a
没有任何关系

释放“b”后使用“a”安全吗

是的,因为
a
b
之间没有持久的关系



基本上,您质疑安全性是C++的一个基本特征,即从函数返回值。返回一个<代码>:ST::SydDypPT/<代码>与返回< <代码> STD::String < /C> >或<代码> int >代码>没有什么不同。当从函数返回值时,总是发生这样的情况:返回。值被复制,原件被销毁,副本继续存在。

可能重复?并且?请发布可编译的代码。例如,没有语法错误,使用正确的
main
\include
s。我已经阅读了这两个问题,但是我决定发布一个新问题,因为我想确保它是安全的(或不安全的)若要执行此操作,则将共享\u ptr作为成员变量的“父”类将超出范围。如果这样做不安全,则我不确定我首先是否理解共享\u ptr的意义。Christian和decltype_auto,您是对的,我只是编辑了代码以使其可编译。
auto a = foo();
return b.get_a();