我目前正在开展一个大项目,我需要使用weak_ptr而不是shared_ptr.
这是我的问题.
我有一个名为House的类,其属性为:vector<boost::shared_ptr<People>> my_people.我想修改这个数据成员vector<boost::weak_ptr<People>> my_people.
我的吸气鬼是
vector<boost::shared_ptr<People>>& getPeople() const
{
return my_people;
}
Run Code Online (Sandbox Code Playgroud)
通常,简单的weak_ptr我可以返回my_people.lock();
但我有一个矢量,我不知道如何做这样的事情:
vector<boost::shared_ptr<People>>& getPeople() const
{
for( vector<boost::weak_ptr<People>::iterator it = my_people.begin();
it != my_people.end();
++it)
{
(*it).lock();
}
return my_people;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,我想返回我的矢量,weak_ptr但作为矢量shared_ptr.可能吗?或者我必须返回一个矢量weak_ptr并lock()在我使用它们的任何地方使用它?
我有一个遵循这种模式的课程:
class Foo
{
public:
// Create a Foo whose value is absolute
Foo(int x) : other_(0), a_(x) {}
// Create a Foo whose value is relative to another Foo
Foo(Foo * other, int dx) : other_(other), a_(dx) {}
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
private:
Foo * other_;
int a_;
};
Run Code Online (Sandbox Code Playgroud)
这些Foo对象都归Bar:
class Bar
{
public:
~Bar() { for(int i=0; i<foos_.size(); i++) delete foos_[i]; …Run Code Online (Sandbox Code Playgroud) 我阅读了关于共享指针并了解如何使用.但我从来没有理解共享指针的循环依赖问题以及弱指针如何解决这些问题.任何人都可以清楚地解释这个问题吗?
当shared_ptr重置为包含的同一地址时,是否可以保证weak_ptr将过期?
#include <cassert>
#include <memory>
int main()
{
int* i = new int(0);
std::shared_ptr<int> si( i );
std::weak_ptr<int> wi = si;
si.reset( i );
assert( wi.expired() ); // wi.expired() == true (GCC 4.7)
}
Run Code Online (Sandbox Code Playgroud)
或者,当wi.expired()未定义值时是这种情况?
编辑:
我现在稍微修改一下这个问题:
是否保证weak_ptr在shared_ptr重置到同一地址时会过期,该地址包含shared_ptr初始化时的地址weak_ptr?
#include <cassert>
#include <memory>
int main()
{
int* i = new int(0);
std::shared_ptr<int> si( i );
std::weak_ptr<int> wi = si;
si.reset();
int* j = new int(0);
// Suppose that new returns the …Run Code Online (Sandbox Code Playgroud) 有时,我们对捕获对象状态的lambda的生命周期一无所知(例如,将其从对象返回,将其注册为回调而无需取消订阅等).如何确保lambda在调用时不会访问已经销毁的对象?
#include <iostream>
#include <memory>
#include <string>
class Foo {
public:
Foo(const std::string& i_name) : name(i_name) {}
std::function<void()> GetPrinter() {
return [this]() {
std::cout << name << std::endl;
};
}
std::string name;
};
int main() {
std::function<void()> f;
{
auto foo = std::make_shared<Foo>("OK");
f = foo->GetPrinter();
}
auto foo = std::make_shared<Foo>("WRONG");
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个程序只是巧合地打印出"错误"而不是"OK"(http://ideone.com/Srp7RC)(似乎它只是为第二个Foo对象重用了相同的内存).无论如何,这是一个错误的计划.Foo我们执行时,第一个对象已经死了f.
似乎有两种方法可以临时获取a所指向的资源的所有权weak_ptr:
lock()weak_ptr给shared_ptr构造函数这两个都产生一个shared_ptr,nullptr如果weak_ptr是空的并且shared_ptr构造函数抛出异常,则锁返回a .
所以问题是:何时应该使用其中一种?是否有与此相关的一般准则或最佳做法?
std::shared_ptr<int> int_ptr;
int main() {
int_ptr = std::make_shared<int>(1);
std::thread th{[&]() {
std::weak_ptr int_ptr_weak = int_ptr;
auto int_ptr_local = int_ptr_weak.lock();
if (int_ptr_local) {
cout << "Value in the shared_ptr is " << *int_ptr_local << endl;
}
});
int_ptr.reset(nullptr);
th.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是否安全?我读了这个答案关于weak_ptr的线程安全,但只是想确保上面的代码是线程安全的.
我问这个的原因是,如果上面的代码确实是线程安全的,我无法理解std::weak_ptr和std::shared_ptr接口如何使以下操作成为原子expired() ? shared_ptr<T>() : shared_ptr<T>(*this).在我看来,如果不使用某种互斥锁或自旋锁,就不能使上面这两行逻辑代码同步.
我理解原子增量如何与不同的共享指针实例一起工作,我理解它们shared_ptr本身不是线程安全的,但如果上面确实是线程安全的,那就非常像线程安全shared_ptr而且我不明白两行代码如何就像在条件上面可以做成原子而没有锁.
鉴于此类是enable_shared_from_this:
class connection : public std::enable_shared_from_this<connection>
{
//...
};
Run Code Online (Sandbox Code Playgroud)
假设我创建的两个实例std::shared_ptr来自同一 connection*如下:
std::shared_ptr<connection> rc(new connection);
std::shared_ptr<connection> fc(rc.get(), [](connection const * c) {
std::cout << "fake delete" << std::endl;
});
Run Code Online (Sandbox Code Playgroud)
到目前为止它的好处,因为资源{ connection*}由一个单独 拥有shared_ptr- rc确切地说,并且fc只有一个假的删除器.
在那之后,我这样做:
auto sc = fc->shared_from_this();
//OR auto sc = rc->shared_from_this(); //does not make any difference!
Run Code Online (Sandbox Code Playgroud)
现在哪个shared_ptr- rc或fc- 将sc 与其分享其引用计数?换一种说法,
std::cout << rc->use_count() << std::endl;
std::cout << fc->use_count() …Run Code Online (Sandbox Code Playgroud) c++ reference-counting shared-ptr weak-ptr enable-shared-from-this
我知道你不能shared_from_this在构造函数中使用。但是可以weak_from_this在构造函数中使用 new吗?根据 cppreference:
这是作为 enable_shared_from_this 一部分的私有可变 weak_ptr 成员的副本。
http://en.cppreference.com/w/cpp/memory/enable_shared_from_this/weak_from_this
我没有看到从构造函数中获取内部存储的 weak_ptr 副本的问题,但我可能会遗漏一些东西,所以我不确定这一点。
我正在学习智能指针和shared_from_this. 在类继承关系中,会很难理解。
我有两个基类CA和CB,它们派生自enable_shared_from_this,子类CC派生自CA和CB。我想从类自身中取出三个类的共享指针,所以我写了sharedCAfromThis,sharedCBfromThis和sharedCCfromthis。
class CA : private enable_shared_from_this<CA> {
public:
shared_ptr<CA> sharedCAfromThis() { return shared_from_this(); }
virtual ~CA() {};
void print() {
cout << "CA" << endl;
}
};
class CB : private enable_shared_from_this<CB> {
public:
shared_ptr<CB> sharedCBfromThis() { return shared_from_this(); }
virtual ~CB() {};
void print() {
cout << "CB" << endl;
}
};
class CC : public CA, …Run Code Online (Sandbox Code Playgroud) c++ ×10
weak-ptr ×10
shared-ptr ×7
c++11 ×5
boost ×1
constructor ×1
inheritance ×1
lambda ×1
vector ×1