在c ++ 0x中,对于std :: shared_ptr有一个std :: static_pointer_cast,但std :: weak_ptr没有等效的方法.这是故意还是疏忽?如果疏忽,我该如何定义合适的功能?
由于我的noob声誉,我无法回复此主题,特别是接受的答案:
我从未使用过boost :: intrusive智能指针,但如果你使用shared_ptr智能指针,你可以使用weak_ptr对象作为缓存.
当系统决定释放内存时,那些weak_ptr指针不算作引用,但只要该对象尚未被删除,它就可用于检索shared_ptr.
这当然是一个直观的想法,但是,C++标准不支持weak_ptrs的比较,因此它不能用作关联容器的键.这可以通过为weak_ptrs实现比较运算符来规避:
template<class Ty1, class Ty2>
bool operator<(
const weak_ptr<Ty1>& _Left,
const weak_ptr<Ty2>& _Right
);
Run Code Online (Sandbox Code Playgroud)
这个解决方案的问题是
(1)比较运算符必须获得每次比较的所有权(即从weak_ptr refs创建shared_ptrs)
(2)当管理资源的最后一个shared_ptr被破坏时,weak_ptr不会从缓存中删除,但是过期的weak_ptr会保留在缓存中.
对于(2),我们可以提供自定义析构函数(DeleteThread),但是,这将需要再次从要删除的T*创建weak_ptr,然后可以使用它从缓存中擦除weak_ptr.
我的问题是,如果有更好的方法使用智能指针缓存(我使用VC100编译器,没有提升),或者我根本没有得到它?
干杯,丹尼尔
我使用的代码库部分由一个爱上过度复杂的简单问题解决方案的人实现(例如,有两个参数的模板类只能为一对类型实例化).她做的一件事是在智能指针中创建对象,然后让对象存储一个指向自身的弱指针.
class MyClass {
//...
boost::weak_ptr<MyClass> m_self;
//...
};
boost::shared_ptr<MyClass>
Factory::Factory::Factory::CreateMyClass() {
boost::shared_ptr<MyClass> obj(new MyClass(...));
boost::weak_ptr<MyClass> p(obj);
obj->storeSelfPointer(p);
return obj;
}
Run Code Online (Sandbox Code Playgroud)
然后,类通过锁定并传递生成的共享指针来继续使用m_self.
对于我的生活,我无法理解她想要完成的事情.是否有一些模式或想法可以解释这种实现?在我看来,这是完全没有意义的,我想重构它.
编辑:我应该提到,使用从锁定m_self获得的结果智能指针的任何地方都没有实际保留智能指针.
有没有人知道的实现shared_ptr,并weak_ptr连同延迟初始化的合作伙伴?这些课程的要求是:
一lazy_ptr类是允许客户端后构造对象(如果有的话),而不需要构造函数实现
一个weak_lazy_ptr有三种可能状态的类:尚未构造(不会锁定到a shared_ptr),构造(将锁定到a shared_ptr)和销毁(不会锁定到a shared_ptr)
我创建了一些类,并没有做的工作完全是前一阵子(见这里CVU文章)所使用shared_ptr,并weak_ptr在他们的执行.使用共享和弱指针而不是与它们集成的模型的主要问题如下:
一旦所有lazy_ptr对象超出范围,即使其他客户端持有shared_ptr版本,也无法再锁定任何弱引用
不能控制不同线程上的对象的构造
我很感激任何指向其他解决这些问题的尝试,或者对这个领域可能正在进行的任何工作的任何指示.
我有一个关于使用std :: weak_ptr作为std :: map的键的问题.
#include <map>
#include <memory>
int main()
{
std::map< std::weak_ptr<int>, bool > myMap;
std::shared_ptr<int> sharedptr(new int(5));
std::weak_ptr<int> weakptr = sharedptr;
myMap[weakptr] = true;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的程序没有构建,并且尝试编译会给出许多错误消息,例如:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::tr1::weak_ptr<_Ty>'
1> with
1> [
1> _Ty=int
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xtree(1885) : see declaration of 'std::operator <' …Run Code Online (Sandbox Code Playgroud) 最近我从C++ 11开始.我研究过weak_ptr.有两种获取原始指针的方法.
lock() 功能
shared_ptr<Foo> spFoo = wpPtr.lock();
if(spFoo) {
spFoo->DoSomething();
}
Run Code Online (Sandbox Code Playgroud)expired() 功能
if(!wpPtr.expired())
{
shared_ptr<Foo> spFoo = wpPtr.lock();
spFoo->DoSomething();
}
Run Code Online (Sandbox Code Playgroud)哪种方式更好?这两种方式有什么不同?
考虑以下代码:
#include <memory>
#include <iostream>
using namespace std;
struct MySharedStruct
{
int i;
};
void print_value_of_i(weak_ptr<MySharedStruct> weakPtr)
{
if (shared_ptr<MySharedStruct> sp = weakPtr.lock())
{ cout << "Value of i = " << sp->i << endl; }
else
{ cout << "Resource has expired"; }
}
int main()
{
shared_ptr<MySharedStruct> sharedPtr(new MySharedStruct() );
sharedPtr->i = 5;
weak_ptr<MySharedStruct> weakPtr;
weakPtr = sharedPtr;
print_value_of_i(weakPtr);
sharedPtr.reset(new MySharedStruct() ); // <<----- How does weak_ptr know it has expired after this line executes?
sharedPtr->i = 10; …Run Code Online (Sandbox Code Playgroud) #include <memory>
#include <iostream>
struct A : public std::enable_shared_from_this<A>
{
~A()
{
auto this_ptr = shared_from_this(); // std::bad_weak_ptr exception here.
std::cout << "this: " << this_ptr;
}
};
int main()
{
auto a = std::make_shared<A>();
a.reset();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我打电话时遇到std::bad_weak_ptr异常shared_from_this().它是按设计的吗?是的,它可能是危险的,因为在析构函数返回后不能使用此指针,但我没有看到为什么在技术上不可能在此处获取指针的原因,因为共享指针对象显然仍然存在并且可以是用过的.有没有办法绕过这个,没有写我自己的enable_shared_from_this模拟(我宁愿做不到)?
似乎weak_ptr某种方式只知道shared_ptr它的引用何时被破坏了.那个怎么样?是否存在持续的链接或什么?
以下面的代码为例:
weak_ptr<int> test() {
shared_ptr<int> foo{new int};
return foo;
}
int main() {
auto foo = test();
cout << foo.expired() << endl;
}
Run Code Online (Sandbox Code Playgroud)
当我weak_ptr<int>去检查状态shared_ptr<int>但是没有一个时,我本来期望一个段错误.在weak_ptr<int>正确地识别存储器中作为释放.怎么知道的?
我有这样的一套: set<weak_ptr<Node>, owner_less<weak_ptr<Node> > > setName;
它工作正常.但我想将它改为无序集.但是,当我这样做时,我得到大约六页的错误.任何想法如何做到这一点?
查看了所有错误消息页面后,我发现了可能有用的行.
/usr/include/c++/4.7/bits/functional_hash.h:60:7: error: static assertion failed: std::hash is not specialized for this type
/usr/include/c++/4.7/bits/stl_function.h: In instantiation of ‘bool std::equal_to<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::weak_ptr<Node>]’:
Run Code Online (Sandbox Code Playgroud) weak-ptr ×10
c++ ×9
shared-ptr ×6
c++11 ×4
caching ×1
destructor ×1
dictionary ×1
refcounting ×1
std ×1
stdmap ×1